Skip to content

Commit 209504f

Browse files
author
Adam Hrbac
committed
Use @child fields instead of insertChildNode
1 parent 6aed9f4 commit 209504f

File tree

1 file changed

+67
-54
lines changed

1 file changed

+67
-54
lines changed

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

Lines changed: 67 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
import com.oracle.graal.python.builtins.objects.dict.PDict;
7070
import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis;
7171
import com.oracle.graal.python.builtins.objects.exception.GetExceptionTracebackNode;
72-
import com.oracle.graal.python.builtins.objects.exception.GetExceptionTracebackNodeGen;
7372
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
7473
import com.oracle.graal.python.builtins.objects.frame.PFrame;
7574
import com.oracle.graal.python.builtins.objects.function.PArguments;
@@ -151,7 +150,6 @@
151150
import com.oracle.graal.python.nodes.frame.DeleteGlobalNode;
152151
import com.oracle.graal.python.nodes.frame.DeleteGlobalNodeGen;
153152
import com.oracle.graal.python.nodes.frame.MaterializeFrameNode;
154-
import com.oracle.graal.python.nodes.frame.MaterializeFrameNodeGen;
155153
import com.oracle.graal.python.nodes.frame.ReadGlobalOrBuiltinNode;
156154
import com.oracle.graal.python.nodes.frame.ReadGlobalOrBuiltinNodeGen;
157155
import com.oracle.graal.python.nodes.frame.ReadNameNode;
@@ -498,6 +496,9 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod
498496
@Child private CalleeContext calleeContext = CalleeContext.create();
499497
@Child private PythonObjectFactory factory = PythonObjectFactory.create();
500498
@Child private ExceptionStateNodes.GetCaughtExceptionNode getCaughtExceptionNode;
499+
@Child private GetExceptionTracebackNode traceGetExceptionTracebackNode = null;
500+
@Child private MaterializeFrameNode traceMaterializeFrameNode = null;
501+
@Child private CallTernaryMethodNode traceCallTernaryMethodNode = null;
501502

502503
private final LoopConditionProfile exceptionChainProfile1 = LoopConditionProfile.createCountingProfile();
503504
private final LoopConditionProfile exceptionChainProfile2 = LoopConditionProfile.createCountingProfile();
@@ -1096,10 +1097,9 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
10961097

10971098
int pastLine = -1;
10981099
if (threadState.getTraceFun() != null && !threadState.isTracing()) {
1099-
MaterializeFrameNode fr = insertChildNode(localNodes, bci, MaterializeFrameNode.getUncached(), MaterializeFrameNodeGen.class, MaterializeFrameNode::create, useCachedNodes);
1100-
pyFrame = fr.execute(virtualFrame, this, true, true);
1100+
pyFrame = ensurePyFrame(virtualFrame, null);
11011101
if (initialBci == 0 || isGeneratorOrCoroutine) {
1102-
pyFrame.setLocalTraceFun(invokeTraceFunction(threadState.getTraceFun(), null, threadState, virtualFrame, pyFrame, 0, localNodes, PythonContext.TraceEvent.CALL, useCachedNodes,
1102+
pyFrame.setLocalTraceFun(invokeTraceFunction(threadState.getTraceFun(), null, threadState, virtualFrame, pyFrame, PythonContext.TraceEvent.CALL,
11031103
initialBci == 0 ? getFirstLineno() : (pastLine = bciToLine(initialBci))));
11041104
}
11051105
} else {
@@ -1114,15 +1114,44 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
11141114
final byte bc = localBC[bci];
11151115
final int beginBci = bci;
11161116
if (threadState.getTraceFun() != null && !threadState.isTracing()) {
1117-
pyFrame = ensurePyFrame(virtualFrame, localNodes, bci, useCachedNodes, pyFrame);
1118-
boolean onANewLine = bciToLine(bci) != pastLine;
1119-
pastLine = bciToLine(bci);
1117+
pyFrame = ensurePyFrame(virtualFrame, pyFrame);
1118+
int thisLine = bciToLine(bci);
1119+
boolean onANewLine = thisLine != pastLine;
1120+
pastLine = thisLine;
11201121
OpCodes c = OpCodes.fromOpCode(localBC[pastBci]);
1121-
if (pyFrame.getLocalTraceFun() != null && pyFrame.getTraceLine() && (pastBci > bci || (onANewLine && (pastBci + c.length() >= bci || bciToLine(bci - 1) != bciToLine(bci))))) {
1122+
/*
1123+
* normally, we trace a line every time the previous bytecode instruction was on a
1124+
* different line than the current one. There are a number of exceptions to this,
1125+
* notably around jumps:
1126+
*
1127+
* - When a backward jumps happens, a line is traced, even if it is the same as the
1128+
* previous one.
1129+
*
1130+
* - When a forward jump happens to the first bytecode instruction of a line, a line
1131+
* is traced.
1132+
*
1133+
* - When a forward jump happens to the middle of a line, a line is not traced.
1134+
*
1135+
* see
1136+
* https://github.com/python/cpython/blob/main/Objects/lnotab_notes.txt#L210-L215
1137+
* for more details
1138+
*/
1139+
boolean shouldTrace = pyFrame.getLocalTraceFun() != null && pyFrame.getTraceLine();
1140+
if (shouldTrace) {
1141+
shouldTrace = pastBci > bci; // is a backward jump
1142+
if (!shouldTrace) {
1143+
shouldTrace = onANewLine &&
1144+
// is not a forward jump
1145+
(pastBci + c.length() >= bci ||
1146+
// is a forward jump to the start of line
1147+
bciToLine(bci - 1) != thisLine);
1148+
}
1149+
}
1150+
if (shouldTrace) {
11221151
returnLine = pastLine;
11231152
pyFrame.setLocalTraceFun(
1124-
invokeTraceFunction(pyFrame.getLocalTraceFun(), null, threadState, virtualFrame, pyFrame, bci, localNodes, PythonContext.TraceEvent.LINE,
1125-
useCachedNodes, pastLine));
1153+
invokeTraceFunction(pyFrame.getLocalTraceFun(), null, threadState, virtualFrame, pyFrame, PythonContext.TraceEvent.LINE,
1154+
pastLine));
11261155
}
11271156
}
11281157
if (threadState.getTraceFun() != null) {
@@ -1583,9 +1612,9 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
15831612
}
15841613
Object value = virtualFrame.getObject(stackTop);
15851614
if (threadState.getTraceFun() != null && !threadState.isTracing()) {
1586-
pyFrame = ensurePyFrame(virtualFrame, localNodes, bci, useCachedNodes, pyFrame);
1615+
pyFrame = ensurePyFrame(virtualFrame, pyFrame);
15871616
if (pyFrame.getLocalTraceFun() != null) {
1588-
invokeTraceFunction(pyFrame.getLocalTraceFun(), value, threadState, virtualFrame, pyFrame, bci, localNodes, PythonContext.TraceEvent.RETURN, useCachedNodes,
1617+
invokeTraceFunction(pyFrame.getLocalTraceFun(), value, threadState, virtualFrame, pyFrame, PythonContext.TraceEvent.RETURN,
15891618
pyFrame.getTraceLine() ? returnLine : bciToLine(bci));
15901619
}
15911620
}
@@ -1863,17 +1892,6 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
18631892
stackTop++;
18641893
bci++;
18651894
} else {
1866-
if (threadState.getTraceFun() != null && !threadState.isTracing()) {
1867-
pyFrame = ensurePyFrame(virtualFrame, localNodes, bci, useCachedNodes, pyFrame);
1868-
if (pyFrame.getLocalTraceFun() != null) {
1869-
pyFrame.setLocalTraceFun(invokeTraceFunction(pyFrame.getLocalTraceFun(),
1870-
factory.createTuple(
1871-
new Object[]{PythonBuiltinClassType.StopIteration, factory.createBaseException(PythonBuiltinClassType.StopIteration), PNone.NONE}),
1872-
threadState, virtualFrame, pyFrame, bci,
1873-
localNodes,
1874-
PythonContext.TraceEvent.EXCEPTION, useCachedNodes, -1));
1875-
}
1876-
}
18771895
virtualFrame.setObject(stackTop--, null);
18781896
oparg |= Byte.toUnsignedInt(localBC[bci + 1]);
18791897
bci += oparg;
@@ -1900,17 +1918,6 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
19001918
stackTop++;
19011919
bci++;
19021920
} else {
1903-
if (threadState.getTraceFun() != null && !threadState.isTracing()) {
1904-
pyFrame = ensurePyFrame(virtualFrame, localNodes, bci, useCachedNodes, pyFrame);
1905-
if (pyFrame.getLocalTraceFun() != null) {
1906-
pyFrame.setLocalTraceFun(invokeTraceFunction(pyFrame.getLocalTraceFun(),
1907-
factory.createTuple(new Object[]{PythonBuiltinClassType.StopIteration, factory.createBaseException(PythonBuiltinClassType.StopIteration),
1908-
PNone.NONE}),
1909-
threadState, virtualFrame, pyFrame, bci,
1910-
localNodes,
1911-
PythonContext.TraceEvent.EXCEPTION, useCachedNodes, -1));
1912-
}
1913-
}
19141921
virtualFrame.setObject(stackTop--, null);
19151922
oparg |= Byte.toUnsignedInt(localBC[bci + 1]);
19161923
bci += oparg;
@@ -2050,10 +2057,10 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
20502057
clearFrameSlots(localFrame, stackTop + 1, initialStackTop);
20512058
}
20522059
if (threadState.getTraceFun() != null && !threadState.isTracing()) {
2053-
pyFrame = ensurePyFrame(virtualFrame, localNodes, bci, useCachedNodes, pyFrame);
2060+
pyFrame = ensurePyFrame(virtualFrame, pyFrame);
20542061
if (pyFrame.getLocalTraceFun() != null) {
2055-
invokeTraceFunction(pyFrame.getLocalTraceFun(), value, threadState, virtualFrame, pyFrame, bci, localNodes, PythonContext.TraceEvent.RETURN,
2056-
useCachedNodes, pyFrame.getTraceLine() ? returnLine : bciToLine(bci));
2062+
invokeTraceFunction(pyFrame.getLocalTraceFun(), value, threadState, virtualFrame, pyFrame, PythonContext.TraceEvent.RETURN,
2063+
pyFrame.getTraceLine() ? returnLine : bciToLine(bci));
20572064
}
20582065
}
20592066
return new GeneratorYieldResult(bci + 1, stackTop, value);
@@ -2144,14 +2151,15 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
21442151
}
21452152

21462153
if (threadState.getTraceFun() != null && !threadState.isTracing() && pe != null) {
2147-
pyFrame = ensurePyFrame(virtualFrame, localNodes, bci, useCachedNodes, pyFrame);
2154+
pyFrame = ensurePyFrame(virtualFrame, pyFrame);
21482155
if (pyFrame.getLocalTraceFun() != null) {
2149-
GetExceptionTracebackNode tbn = insertChildNode(localNodes, bci, GetExceptionTracebackNode.getUncached(), GetExceptionTracebackNodeGen.class, GetExceptionTracebackNode::create, useCachedNodes);
2150-
Object tb = tbn.execute(pe);
2156+
if (traceGetExceptionTracebackNode == null) {
2157+
traceGetExceptionTracebackNode = GetExceptionTracebackNode.create();
2158+
}
2159+
Object traceback = traceGetExceptionTracebackNode.execute(pe);
21512160
pyFrame.setLocalTraceFun(invokeTraceFunction(pyFrame.getLocalTraceFun(),
2152-
factory.createTuple(new Object[]{pe.getClass(), pe.setCatchingFrameAndGetEscapedException(virtualFrame, this), tb}), threadState, virtualFrame, pyFrame, bci,
2153-
localNodes,
2154-
PythonContext.TraceEvent.EXCEPTION, useCachedNodes, -1));
2161+
factory.createTuple(new Object[]{pe.getClass(), pe.setCatchingFrameAndGetEscapedException(virtualFrame, this), traceback}), threadState, virtualFrame, pyFrame,
2162+
PythonContext.TraceEvent.EXCEPTION, -1));
21552163
}
21562164
}
21572165

@@ -2184,9 +2192,9 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
21842192
LoopNode.reportLoopCount(this, mutableData.loopCount);
21852193
}
21862194
if (threadState.getTraceFun() != null) {
2187-
pyFrame = ensurePyFrame(virtualFrame, localNodes, bci, useCachedNodes, pyFrame);
2195+
pyFrame = ensurePyFrame(virtualFrame, pyFrame);
21882196
if (pyFrame.getLocalTraceFun() != null) {
2189-
invokeTraceFunction(pyFrame.getLocalTraceFun(), PNone.NONE, threadState, virtualFrame, pyFrame, bci, localNodes, PythonContext.TraceEvent.RETURN, useCachedNodes,
2197+
invokeTraceFunction(pyFrame.getLocalTraceFun(), PNone.NONE, threadState, virtualFrame, pyFrame, PythonContext.TraceEvent.RETURN,
21902198
pyFrame.getTraceLine() ? returnLine : bciToLine(bci));
21912199
}
21922200
}
@@ -2214,24 +2222,29 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
22142222
}
22152223
}
22162224

2217-
private PFrame ensurePyFrame(VirtualFrame virtualFrame, Node[] localNodes, int bci, boolean useCachedNodes, PFrame pyFrame) {
2225+
private PFrame ensurePyFrame(VirtualFrame virtualFrame, PFrame pyFrame) {
2226+
if (traceMaterializeFrameNode == null) {
2227+
traceMaterializeFrameNode = MaterializeFrameNode.create();
2228+
}
22182229
if (pyFrame == null) {
2219-
MaterializeFrameNode fr = insertChildNode(localNodes, bci, MaterializeFrameNode.getUncached(), MaterializeFrameNodeGen.class, MaterializeFrameNode::create, useCachedNodes);
2220-
return fr.execute(virtualFrame, this, true, true);
2230+
return traceMaterializeFrameNode.execute(virtualFrame, this, true, true);
22212231
}
22222232
return pyFrame;
22232233
}
2234+
// TODO: trace with OSR in a generator will create extraneous call events
22242235

2225-
private Object invokeTraceFunction(Object traceFn, Object arg, PythonContext.PythonThreadState threadState, VirtualFrame virtualFrame, PFrame tracing, int bci,
2226-
Node[] localNodes, PythonContext.TraceEvent ev, boolean useCachedNodes, int line) {
2227-
threadState.tracingStart(ev);
2228-
CallTernaryMethodNode callNode = insertChildNode(localNodes, bci, UNCACHED_CALL_TERNARY_METHOD, CallTernaryMethodNodeGen.class, NODE_CALL_TERNARY_METHOD, useCachedNodes);
2236+
private Object invokeTraceFunction(Object traceFn, Object arg, PythonContext.PythonThreadState threadState, VirtualFrame virtualFrame, PFrame tracing,
2237+
PythonContext.TraceEvent event, int line) {
2238+
threadState.tracingStart(event);
22292239
Object nonNullArg = arg == null ? PNone.NONE : arg;
2240+
if (traceCallTernaryMethodNode == null) {
2241+
traceCallTernaryMethodNode = CallTernaryMethodNode.create();
2242+
}
22302243
try {
22312244
if (line != -1) {
22322245
tracing.setLineLock(line);
22332246
}
2234-
Object result = callNode.execute(virtualFrame, traceFn, tracing, ev.pythonName, nonNullArg);
2247+
Object result = traceCallTernaryMethodNode.execute(virtualFrame, traceFn, tracing, event.pythonName, nonNullArg);
22352248
return result == PNone.NONE ? null : result;
22362249
} catch (Throwable e) {
22372250
threadState.setTraceFun(null);

0 commit comments

Comments
 (0)