Skip to content

Commit d0eda62

Browse files
committed
Simplify tracing calls
1 parent c968d77 commit d0eda62

File tree

2 files changed

+33
-88
lines changed

2 files changed

+33
-88
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java

Lines changed: 10 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,7 @@
222222
import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
223223
import com.oracle.graal.python.nodes.util.CastToJavaIntExactNodeGen;
224224
import com.oracle.graal.python.nodes.util.ExceptionStateNodes;
225-
import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext;
226225
import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext;
227-
import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData;
228226
import com.oracle.graal.python.runtime.PythonContext;
229227
import com.oracle.graal.python.runtime.PythonOptions;
230228
import com.oracle.graal.python.runtime.exception.ExceptionUtils;
@@ -599,7 +597,6 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod
599597
@Child private CalleeContext calleeContext = CalleeContext.create();
600598
@Child private ExceptionStateNodes.GetCaughtExceptionNode getCaughtExceptionNode;
601599
@Child private ChainExceptionsNode chainExceptionsNode;
602-
@Child private BoundaryCallData profilingAndTracingBoundaryCallData;
603600

604601
private static final byte TRACE_PROFILE_LINE = 1;
605602
private static final byte TRACE_PROFILE_NEW_FRAME = 1 << 1;
@@ -610,6 +607,8 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod
610607
private static final class TracingNodes extends Node {
611608
@Child MaterializeFrameNode traceMaterializeFrameNewNode = MaterializeFrameNode.create();
612609
@Child MaterializeFrameNode traceMaterializeFrameExistingNode = MaterializeFrameNode.create();
610+
@Child CallNode tracingCallNode = CallNode.create();
611+
@Child CallNode profilingCallNode = CallNode.create();
613612
@CompilationFinal(dimensions = 1) byte[] traceProfileData;
614613

615614
public TracingNodes(int bytecodeLength) {
@@ -3267,10 +3266,10 @@ private PFrame ensurePyFrame(VirtualFrame virtualFrame, int bci) {
32673266
PFrame pyFrame = PArguments.getCurrentFrameInfo(virtualFrame).getPyFrame();
32683267
if (pyFrame == null) {
32693268
enterTraceProfile(bci, TRACE_PROFILE_NEW_FRAME);
3270-
return getTracingNodes().traceMaterializeFrameNewNode.executeOnStack(virtualFrame, this, true, true);
3269+
return getTracingNodes().traceMaterializeFrameNewNode.executeOnStack(virtualFrame, this, true, false);
32713270
} else {
32723271
enterTraceProfile(bci, TRACE_PROFILE_EXISTING_FRAME);
3273-
return getTracingNodes().traceMaterializeFrameExistingNode.executeOnStack(virtualFrame, this, true, true);
3272+
return getTracingNodes().traceMaterializeFrameExistingNode.executeOnStack(virtualFrame, this, true, false);
32743273
}
32753274
}
32763275

@@ -3284,26 +3283,19 @@ private void invokeTraceFunction(VirtualFrame virtualFrame, Object arg, PythonCo
32843283
threadState.tracingStart(event);
32853284
PFrame pyFrame = mutableData.setPyFrame(ensurePyFrame(virtualFrame, bci));
32863285
Object traceFn = useLocalFn ? pyFrame.getLocalTraceFun() : threadState.getTraceFun();
3286+
32873287
if (traceFn == null) {
32883288
threadState.tracingStop();
32893289
return;
32903290
}
3291+
3292+
pyFrame.setLocalsAccessed(false);
32913293
Object nonNullArg = arg == null ? PNone.NONE : arg;
32923294
try {
32933295
if (line != -1) {
32943296
pyFrame.setLineLock(line);
32953297
}
3296-
if (profilingAndTracingBoundaryCallData == null) {
3297-
CompilerDirectives.transferToInterpreterAndInvalidate();
3298-
profilingAndTracingBoundaryCallData = insert(BoundaryCallData.createFor(this));
3299-
}
3300-
Object savedState = BoundaryCallContext.enter(virtualFrame, threadState, profilingAndTracingBoundaryCallData);
3301-
Object result;
3302-
try {
3303-
result = doInvokeTraceFunction(event, pyFrame, traceFn, nonNullArg);
3304-
} finally {
3305-
BoundaryCallContext.exit(virtualFrame, threadState, savedState);
3306-
}
3298+
Object result = getTracingNodes().tracingCallNode.execute(virtualFrame, traceFn, pyFrame, event.pythonName, nonNullArg);
33073299
syncLocalsBackToFrame(virtualFrame, pyFrame, bci);
33083300
// https://github.com/python/cpython/issues/104232
33093301
if (useLocalFn) {
@@ -3333,14 +3325,6 @@ public Frame getLocalFrame(VirtualFrame frame) {
33333325
}
33343326
}
33353327

3336-
@TruffleBoundary
3337-
private static Object doInvokeTraceFunction(PythonContext.TraceEvent event, PFrame pyFrame, Object traceFn, Object nonNullArg) {
3338-
// Force locals dict sync, so that we can sync them back later
3339-
GetFrameLocalsNode.executeUncached(pyFrame, true);
3340-
pyFrame.setLocalsAccessed(false);
3341-
return CallTernaryMethodNode.getUncached().execute(null, traceFn, pyFrame, event.pythonName, nonNullArg);
3342-
}
3343-
33443328
private void syncLocalsBackToFrame(VirtualFrame virtualFrame, PFrame pyFrame, int bci) {
33453329
Frame localFrame = getLocalFrame(virtualFrame);
33463330
if (pyFrame.localsAccessed()) {
@@ -3384,18 +3368,9 @@ private void invokeProfileFunction(VirtualFrame virtualFrame, Object arg, Python
33843368
return;
33853369
}
33863370

3371+
pyFrame.setLocalsAccessed(false);
33873372
try {
3388-
if (profilingAndTracingBoundaryCallData == null) {
3389-
CompilerDirectives.transferToInterpreterAndInvalidate();
3390-
profilingAndTracingBoundaryCallData = insert(BoundaryCallData.createFor(this));
3391-
}
3392-
Object savedState = BoundaryCallContext.enter(virtualFrame, threadState, profilingAndTracingBoundaryCallData);
3393-
Object result;
3394-
try {
3395-
result = doInvokeProfileFunction(arg, event, pyFrame, profileFun);
3396-
} finally {
3397-
BoundaryCallContext.exit(virtualFrame, threadState, savedState);
3398-
}
3373+
Object result = getTracingNodes().profilingCallNode.execute(virtualFrame, profileFun, pyFrame, event.name, arg == null ? PNone.NONE : arg);
33993374
syncLocalsBackToFrame(virtualFrame, pyFrame, bci);
34003375
Object realResult = result == PNone.NONE ? null : result;
34013376
pyFrame.setLocalTraceFun(realResult);
@@ -3407,14 +3382,6 @@ private void invokeProfileFunction(VirtualFrame virtualFrame, Object arg, Python
34073382
}
34083383
}
34093384

3410-
@TruffleBoundary
3411-
private static Object doInvokeProfileFunction(Object arg, PythonContext.ProfileEvent event, PFrame pyFrame, Object profileFun) {
3412-
// Force locals dict sync, so that we can sync them back later
3413-
GetFrameLocalsNode.executeUncached(pyFrame, false);
3414-
pyFrame.setLocalsAccessed(false);
3415-
return CallTernaryMethodNode.getUncached().execute(null, profileFun, pyFrame, event.name, arg == null ? PNone.NONE : arg);
3416-
}
3417-
34183385
@ExplodeLoop
34193386
private void unboxVariables(Frame localFrame) {
34203387
/*

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode_dsl/PBytecodeDSLRootNode.java

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@
216216
import com.oracle.graal.python.nodes.object.GetClassNode.GetPythonObjectClassNode;
217217
import com.oracle.graal.python.nodes.object.IsNode;
218218
import com.oracle.graal.python.nodes.util.ExceptionStateNodes;
219-
import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext;
220219
import com.oracle.graal.python.runtime.ExecutionContext.CalleeContext;
221220
import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData;
222221
import com.oracle.graal.python.runtime.PythonContext;
@@ -284,7 +283,6 @@
284283
import com.oracle.truffle.api.frame.MaterializedFrame;
285284
import com.oracle.truffle.api.frame.VirtualFrame;
286285
import com.oracle.truffle.api.library.CachedLibrary;
287-
import com.oracle.truffle.api.nodes.EncapsulatingNodeReference;
288286
import com.oracle.truffle.api.nodes.ExplodeLoop;
289287
import com.oracle.truffle.api.nodes.Node;
290288
import com.oracle.truffle.api.nodes.UnexpectedResultException;
@@ -362,9 +360,16 @@ public abstract class PBytecodeDSLRootNode extends PRootNode implements Bytecode
362360

363361
@Child private transient CalleeContext calleeContext = CalleeContext.create();
364362
@Child private transient ExceptionStateNodes.GetCaughtExceptionNode getCaughtExceptionNode;
365-
@Child private transient MaterializeFrameNode traceMaterializeFrameNode = null;
366363
@Child private transient ChainExceptionsNode chainExceptionsNode;
367-
@Child private transient BoundaryCallData tracingAndProfilingBoundaryCallData;
364+
365+
private static final class TracingNodes extends Node {
366+
@Child MaterializeFrameNode materializeFrameNode = MaterializeFrameNode.create();
367+
@Child CallNode tracingCallNode = CallNode.create();
368+
@Child CallNode profilingCallNode = CallNode.create();
369+
}
370+
371+
// Not a child of this root, adopted by the BytecodeNode
372+
private transient TracingNodes tracingNodes;
368373

369374
// These fields are effectively final, but can only be set after construction.
370375
@CompilationFinal protected transient BytecodeDSLCodeUnit co;
@@ -532,12 +537,20 @@ public final void ensureTraceAndProfileEnabled() {
532537
getRootNodes().update(TRACE_AND_PROFILE_CONFIG);
533538
}
534539

535-
private PFrame ensurePyFrame(VirtualFrame frame, BytecodeNode location) {
536-
if (traceMaterializeFrameNode == null) {
540+
private TracingNodes getTracingNodes(BytecodeNode location) {
541+
/*
542+
* The TracingNodes node must be child of the BytecodeNode and not the PBytecodeRootNode, so
543+
* in case BytecodeNode changed, we must reinsert it
544+
*/
545+
if (tracingNodes == null || tracingNodes.getParent() != location) {
537546
CompilerDirectives.transferToInterpreterAndInvalidate();
538-
traceMaterializeFrameNode = insert(MaterializeFrameNode.create());
547+
tracingNodes = location.insert(new TracingNodes());
539548
}
540-
return traceMaterializeFrameNode.executeOnStack(frame, location, true, true);
549+
return tracingNodes;
550+
}
551+
552+
private PFrame ensurePyFrame(VirtualFrame frame, BytecodeNode location) {
553+
return getTracingNodes(location).materializeFrameNode.executeOnStack(frame, location, true, false);
541554
}
542555

543556
private void syncLocalsBackToFrame(VirtualFrame frame, PFrame pyFrame, BytecodeNode location) {
@@ -546,31 +559,6 @@ private void syncLocalsBackToFrame(VirtualFrame frame, PFrame pyFrame, BytecodeN
546559
}
547560
}
548561

549-
/**
550-
* When tracing/profiling is enabled, we emit a lot of extra operations. Reduce compiled code
551-
* size by putting the calls behind a boundary (the uncached invoke will eventually perform an
552-
* indirect call anyway).
553-
*/
554-
@TruffleBoundary
555-
private static Object doInvokeProfileOrTraceFunctionBoundary(Object fun, PFrame pyFrame, TruffleString eventName, Object arg) {
556-
return CallTernaryMethodNode.getUncached().execute(null, fun, pyFrame, eventName, arg == null ? PNone.NONE : arg);
557-
}
558-
559-
private Object doInvokeProfileOrTraceFunction(VirtualFrame frame, BytecodeNode location, PythonThreadState threadState, Object fun, PFrame pyFrame, TruffleString eventName, Object arg) {
560-
if (tracingAndProfilingBoundaryCallData == null || tracingAndProfilingBoundaryCallData.getParent() != location) {
561-
// The IndirectCallData node must be child of the BytecodeNode and not the
562-
// PBytecodeRootNode, so in case BytecodeNode changed, we must reinsert it
563-
CompilerDirectives.transferToInterpreterAndInvalidate();
564-
tracingAndProfilingBoundaryCallData = location.insert(BoundaryCallData.createFor(this));
565-
}
566-
Object saved = BoundaryCallContext.enter(frame, threadState, tracingAndProfilingBoundaryCallData);
567-
try {
568-
return doInvokeProfileOrTraceFunctionBoundary(fun, pyFrame, eventName, arg);
569-
} finally {
570-
BoundaryCallContext.exit(frame, threadState, saved);
571-
}
572-
}
573-
574562
@InliningCutoff
575563
private void invokeProfileFunction(VirtualFrame virtualFrame, BytecodeNode location, Object profileFun,
576564
PythonContext.PythonThreadState threadState, PythonContext.ProfileEvent event, Object arg) {
@@ -579,13 +567,9 @@ private void invokeProfileFunction(VirtualFrame virtualFrame, BytecodeNode locat
579567
}
580568
threadState.profilingStart();
581569
PFrame pyFrame = ensurePyFrame(virtualFrame, location);
582-
EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent();
583-
Node oldEncapsulatingNode = encapsulating.set(location);
584570
try {
585-
// Force locals dict sync, so that we can sync them back later
586-
GetFrameLocalsNode.executeUncached(pyFrame, false);
587571
pyFrame.setLocalsAccessed(false);
588-
Object result = doInvokeProfileOrTraceFunction(virtualFrame, location, threadState, profileFun, pyFrame, event.name, arg);
572+
Object result = getTracingNodes(location).profilingCallNode.execute(virtualFrame, profileFun, pyFrame, event.name, arg == null ? PNone.NONE : arg);
589573
syncLocalsBackToFrame(virtualFrame, pyFrame, location);
590574
Object realResult = result == PNone.NONE ? null : result;
591575
pyFrame.setLocalTraceFun(realResult);
@@ -594,7 +578,6 @@ private void invokeProfileFunction(VirtualFrame virtualFrame, BytecodeNode locat
594578
throw e;
595579
} finally {
596580
threadState.profilingStop();
597-
encapsulating.set(oldEncapsulatingNode);
598581
}
599582
}
600583

@@ -619,8 +602,6 @@ private void invokeTraceFunction(VirtualFrame virtualFrame, BytecodeNode locatio
619602
}
620603
Object nonNullArg = arg == null ? PNone.NONE : arg;
621604

622-
EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent();
623-
Node oldEncapsulatingNode = encapsulating.set(location);
624605
try {
625606
/**
626607
* The PFrame syncs to the line of the current bci. Sometimes this location is
@@ -631,10 +612,8 @@ private void invokeTraceFunction(VirtualFrame virtualFrame, BytecodeNode locatio
631612
pyFrame.setLineLock(line);
632613
}
633614

634-
// Force locals dict sync, so that we can sync them back later
635-
GetFrameLocalsNode.executeUncached(pyFrame, true);
636615
pyFrame.setLocalsAccessed(false);
637-
Object result = doInvokeProfileOrTraceFunction(virtualFrame, location, threadState, traceFn, pyFrame, event.pythonName, nonNullArg);
616+
Object result = getTracingNodes(location).tracingCallNode.execute(virtualFrame, traceFn, pyFrame, event.pythonName, nonNullArg);
638617
syncLocalsBackToFrame(virtualFrame, pyFrame, location);
639618
// https://github.com/python/cpython/issues/104232
640619
if (useLocalFn) {
@@ -653,7 +632,6 @@ private void invokeTraceFunction(VirtualFrame virtualFrame, BytecodeNode locatio
653632
pyFrame.lineUnlock();
654633
}
655634
threadState.tracingStop();
656-
encapsulating.set(oldEncapsulatingNode);
657635
}
658636
}
659637

0 commit comments

Comments
 (0)