Skip to content

Commit 0e9b614

Browse files
committed
Extract methods to reduce bytecodeLoop size
1 parent 249c4a3 commit 0e9b614

File tree

1 file changed

+113
-72
lines changed

1 file changed

+113
-72
lines changed

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

Lines changed: 113 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@
199199
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
200200
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
201201
import com.oracle.truffle.api.CompilerDirectives.ValueType;
202-
import com.oracle.truffle.api.HostCompilerDirectives;
203202
import com.oracle.truffle.api.HostCompilerDirectives.BytecodeInterpreterSwitch;
203+
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
204204
import com.oracle.truffle.api.Truffle;
205205
import com.oracle.truffle.api.TruffleLanguage;
206206
import com.oracle.truffle.api.TruffleSafepoint;
@@ -1162,56 +1162,20 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
11621162
CompilerAsserts.partialEvaluationConstant(bci);
11631163
CompilerAsserts.partialEvaluationConstant(stackTop);
11641164

1165+
boolean tracingEnabled = isTracingEnabled(noTrace, mutableData);
11651166
// if we are simply continuing to run an OSR loop after the replacement, tracing an
11661167
// extra CALL event would be incorrect
1167-
if (!noTrace.isValid() && mutableData.getThreadState(this).getTraceFun() != null && !fromOSR) {
1168-
invokeTraceFunction(virtualFrame, null, mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.CALL,
1169-
initialBci == 0 ? getFirstLineno() : (mutableData.setPastLine(bciToLine(initialBci))), false);
1168+
if (tracingEnabled && !fromOSR) {
1169+
traceCall(virtualFrame, initialBci, mutableData);
11701170
}
11711171

11721172
int oparg = 0;
11731173
while (true) {
11741174
final byte bc = localBC[bci];
11751175
final int beginBci = bci;
1176-
if (!noTrace.isValid() && mutableData.getThreadState(this).getTraceFun() != null) {
1177-
int thisLine = bciToLine(bci);
1178-
boolean onANewLine = thisLine != mutableData.getPastLine();
1179-
mutableData.setPastLine(thisLine);
1180-
OpCodes c = OpCodes.fromOpCode(localBC[mutableData.getPastBci()]);
1181-
/*
1182-
* normally, we trace a line every time the previous bytecode instruction was on a
1183-
* different line than the current one. There are a number of exceptions to this,
1184-
* notably around jumps:
1185-
*
1186-
* - When a backward jumps happens, a line is traced, even if it is the same as the
1187-
* previous one.
1188-
*
1189-
* - When a forward jump happens to the first bytecode instruction of a line, a line
1190-
* is traced.
1191-
*
1192-
* - When a forward jump happens to the middle of a line, a line is not traced.
1193-
*
1194-
* see
1195-
* https://github.com/python/cpython/blob/main/Objects/lnotab_notes.txt#L210-L215
1196-
* for more details
1197-
*/
1198-
boolean shouldTrace = mutableData.getPastBci() > bci; // is a backward jump
1199-
if (!shouldTrace) {
1200-
shouldTrace = onANewLine &&
1201-
// is not a forward jump
1202-
(mutableData.getPastBci() + c.length() >= bci ||
1203-
// is a forward jump to the start of line
1204-
bciToLine(bci - 1) != thisLine);
1205-
}
1206-
if (shouldTrace) {
1207-
mutableData.setReturnLine(mutableData.getPastLine());
1208-
mutableData.setPyFrame(ensurePyFrame(virtualFrame, mutableData.getPyFrame()));
1209-
if (mutableData.getPyFrame().getTraceLine()) {
1210-
invokeTraceFunction(virtualFrame, null, mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.LINE,
1211-
mutableData.getPastLine(), true);
1212-
}
1213-
}
1214-
mutableData.setPastBci(bci);
1176+
tracingEnabled = isTracingEnabled(noTrace, mutableData);
1177+
if (tracingEnabled) {
1178+
traceLine(virtualFrame, mutableData, localBC, bci);
12151179
}
12161180

12171181
CompilerAsserts.partialEvaluationConstant(bc);
@@ -1647,10 +1611,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
16471611
}
16481612
case OpCodesConstants.BINARY_SUBSCR: {
16491613
setCurrentBci(virtualFrame, bciSlot, bci);
1650-
GetItemNode getItemNode = insertChildNode(localNodes, bci, GetItemNodeGen.class, NODE_GET_ITEM);
1651-
Object slice = virtualFrame.getObject(stackTop);
1652-
virtualFrame.setObject(stackTop--, null);
1653-
virtualFrame.setObject(stackTop, getItemNode.execute(virtualFrame, virtualFrame.getObject(stackTop), slice));
1614+
stackTop = bytecodeBinarySubscr(virtualFrame, stackTop, bci, localNodes);
16541615
break;
16551616
}
16561617
case OpCodesConstants.STORE_SUBSCR: {
@@ -1672,9 +1633,8 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
16721633
LoopNode.reportLoopCount(this, mutableData.loopCount);
16731634
}
16741635
Object value = virtualFrame.getObject(stackTop);
1675-
if (!noTrace.isValid() && mutableData.getThreadState(this).getTraceFun() != null) {
1676-
invokeTraceFunction(virtualFrame, value, mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.RETURN,
1677-
mutableData.getReturnLine(), true);
1636+
if (tracingEnabled) {
1637+
traceReturn(virtualFrame, mutableData, value);
16781638
}
16791639
if (isGeneratorOrCoroutine) {
16801640
throw new GeneratorReturnException(value);
@@ -2114,9 +2074,8 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
21142074
// Clear slots that were popped (if any)
21152075
clearFrameSlots(localFrame, stackTop + 1, initialStackTop);
21162076
}
2117-
if (!noTrace.isValid() && mutableData.getThreadState(this).getTraceFun() != null) {
2118-
invokeTraceFunction(virtualFrame, value, mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.RETURN,
2119-
mutableData.getReturnLine(), true);
2077+
if (tracingEnabled) {
2078+
traceYield(virtualFrame, mutableData, value);
21202079
}
21212080
return new GeneratorYieldResult(bci + 1, stackTop, value);
21222081
}
@@ -2167,10 +2126,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
21672126
}
21682127
}
21692128
case OpCodesConstants.PRINT_EXPR: {
2170-
setCurrentBci(virtualFrame, bciSlot, bci);
2171-
PrintExprNode printExprNode = insertChildNode(localNodes, beginBci, UNCACHED_PRINT_EXPR, PrintExprNodeGen.class, NODE_PRINT_EXPR, useCachedNodes);
2172-
printExprNode.execute(virtualFrame, virtualFrame.getObject(stackTop));
2173-
virtualFrame.setObject(stackTop--, null);
2129+
stackTop = bytecodePrintExpr(virtualFrame, useCachedNodes, stackTop, bci, localNodes, bciSlot, beginBci);
21742130
break;
21752131
}
21762132
case OpCodesConstants.EXTENDED_ARG: {
@@ -2205,17 +2161,9 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
22052161
}
22062162
}
22072163

2208-
if (!noTrace.isValid() && mutableData.getThreadState(this).getTraceFun() != null && !mutableData.getThreadState(this).isTracing() && pe != null) {
2209-
mutableData.setPyFrame(ensurePyFrame(virtualFrame, mutableData.getPyFrame()));
2210-
if (mutableData.getPyFrame().getLocalTraceFun() != null) {
2211-
Object traceback = GetExceptionTracebackNode.getUncached().execute(pe);
2212-
PBaseException peForPython = pe.setCatchingFrameAndGetEscapedException(virtualFrame, this);
2213-
Object peType = GetClassNode.getUncached().execute(peForPython);
2214-
invokeTraceFunction(virtualFrame,
2215-
factory.createTuple(new Object[]{peType, peForPython, traceback}), mutableData.getThreadState(this),
2216-
mutableData,
2217-
PythonContext.TraceEvent.EXCEPTION, bciToLine(bci), true);
2218-
}
2164+
tracingEnabled = isTracingEnabled(noTrace, mutableData);
2165+
if (tracingEnabled && pe != null && !mutableData.getThreadState(this).isTracing()) {
2166+
traceException(virtualFrame, mutableData, bci, pe);
22192167
}
22202168

22212169
int targetIndex = findHandler(beginBci);
@@ -2246,9 +2194,8 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
22462194
if (CompilerDirectives.hasNextTier() && mutableData.loopCount > 0) {
22472195
LoopNode.reportLoopCount(this, mutableData.loopCount);
22482196
}
2249-
if (!noTrace.isValid() && mutableData.getThreadState(this).getTraceFun() != null) {
2250-
invokeTraceFunction(virtualFrame, PNone.NONE, mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.RETURN,
2251-
mutableData.getReturnLine(), true);
2197+
if (tracingEnabled) {
2198+
traceReturn(virtualFrame, mutableData, PNone.NONE);
22522199
}
22532200
if (e == pe) {
22542201
throw pe;
@@ -2274,6 +2221,101 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
22742221
}
22752222
}
22762223

2224+
@InliningCutoff // Used only to print expressions in interactive mode
2225+
private int bytecodePrintExpr(VirtualFrame virtualFrame, boolean useCachedNodes, int stackTop, int bci, Node[] localNodes, int bciSlot, int beginBci) {
2226+
setCurrentBci(virtualFrame, bciSlot, bci);
2227+
PrintExprNode printExprNode = insertChildNode(localNodes, beginBci, UNCACHED_PRINT_EXPR, PrintExprNodeGen.class, NODE_PRINT_EXPR, useCachedNodes);
2228+
printExprNode.execute(virtualFrame, virtualFrame.getObject(stackTop));
2229+
virtualFrame.setObject(stackTop--, null);
2230+
return stackTop;
2231+
}
2232+
2233+
private boolean isTracingEnabled(Assumption noTrace, MutableLoopData mutableData) {
2234+
return !noTrace.isValid() && mutableData.getThreadState(this).getTraceFun() != null;
2235+
}
2236+
2237+
@InliningCutoff
2238+
private void traceYield(VirtualFrame virtualFrame, MutableLoopData mutableData, Object value) {
2239+
invokeTraceFunction(virtualFrame, value, mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.RETURN,
2240+
mutableData.getReturnLine(), true);
2241+
}
2242+
2243+
@InliningCutoff
2244+
private void traceReturn(VirtualFrame virtualFrame, MutableLoopData mutableData, Object value) {
2245+
invokeTraceFunction(virtualFrame, value, mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.RETURN,
2246+
mutableData.getReturnLine(), true);
2247+
}
2248+
2249+
@InliningCutoff
2250+
private void traceException(VirtualFrame virtualFrame, MutableLoopData mutableData, int bci, PException pe) {
2251+
mutableData.setPyFrame(ensurePyFrame(virtualFrame, mutableData.getPyFrame()));
2252+
if (mutableData.getPyFrame().getLocalTraceFun() != null) {
2253+
Object traceback = GetExceptionTracebackNode.getUncached().execute(pe);
2254+
PBaseException peForPython = pe.setCatchingFrameAndGetEscapedException(virtualFrame, this);
2255+
Object peType = GetClassNode.getUncached().execute(peForPython);
2256+
invokeTraceFunction(virtualFrame,
2257+
factory.createTuple(new Object[]{peType, peForPython, traceback}), mutableData.getThreadState(this),
2258+
mutableData,
2259+
PythonContext.TraceEvent.EXCEPTION, bciToLine(bci), true);
2260+
}
2261+
}
2262+
2263+
@InliningCutoff
2264+
private void traceCall(VirtualFrame virtualFrame, int initialBci, MutableLoopData mutableData) {
2265+
invokeTraceFunction(virtualFrame, null, mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.CALL,
2266+
initialBci == 0 ? getFirstLineno() : (mutableData.setPastLine(bciToLine(initialBci))), false);
2267+
}
2268+
2269+
@InliningCutoff
2270+
private void traceLine(VirtualFrame virtualFrame, MutableLoopData mutableData, byte[] localBC, int bci) {
2271+
int thisLine = bciToLine(bci);
2272+
boolean onANewLine = thisLine != mutableData.getPastLine();
2273+
mutableData.setPastLine(thisLine);
2274+
OpCodes c = OpCodes.fromOpCode(localBC[mutableData.getPastBci()]);
2275+
/*
2276+
* normally, we trace a line every time the previous bytecode instruction was on a different
2277+
* line than the current one. There are a number of exceptions to this, notably around
2278+
* jumps:
2279+
*
2280+
* - When a backward jumps happens, a line is traced, even if it is the same as the previous
2281+
* one.
2282+
*
2283+
* - When a forward jump happens to the first bytecode instruction of a line, a line is
2284+
* traced.
2285+
*
2286+
* - When a forward jump happens to the middle of a line, a line is not traced.
2287+
*
2288+
* see https://github.com/python/cpython/blob/main/Objects/lnotab_notes.txt#L210-L215 for
2289+
* more details
2290+
*/
2291+
boolean shouldTrace = mutableData.getPastBci() > bci; // is a backward jump
2292+
if (!shouldTrace) {
2293+
shouldTrace = onANewLine &&
2294+
// is not a forward jump
2295+
(mutableData.getPastBci() + c.length() >= bci ||
2296+
// is a forward jump to the start of line
2297+
bciToLine(bci - 1) != thisLine);
2298+
}
2299+
if (shouldTrace) {
2300+
mutableData.setReturnLine(mutableData.getPastLine());
2301+
mutableData.setPyFrame(ensurePyFrame(virtualFrame, mutableData.getPyFrame()));
2302+
if (mutableData.getPyFrame().getTraceLine()) {
2303+
invokeTraceFunction(virtualFrame, null, mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.LINE,
2304+
mutableData.getPastLine(), true);
2305+
}
2306+
}
2307+
mutableData.setPastBci(bci);
2308+
}
2309+
2310+
@BytecodeInterpreterSwitch
2311+
private int bytecodeBinarySubscr(VirtualFrame virtualFrame, int stackTop, int bci, Node[] localNodes) {
2312+
GetItemNode getItemNode = insertChildNode(localNodes, bci, GetItemNodeGen.class, NODE_GET_ITEM);
2313+
Object slice = virtualFrame.getObject(stackTop);
2314+
virtualFrame.setObject(stackTop--, null);
2315+
virtualFrame.setObject(stackTop, getItemNode.execute(virtualFrame, virtualFrame.getObject(stackTop), slice));
2316+
return stackTop;
2317+
}
2318+
22772319
private PFrame ensurePyFrame(VirtualFrame virtualFrame, PFrame pyFrame) {
22782320
if (traceMaterializeFrameNode == null) {
22792321
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -2285,7 +2327,6 @@ private PFrame ensurePyFrame(VirtualFrame virtualFrame, PFrame pyFrame) {
22852327
return pyFrame;
22862328
}
22872329

2288-
@HostCompilerDirectives.InliningCutoff
22892330
private void invokeTraceFunction(VirtualFrame virtualFrame, Object arg, PythonContext.PythonThreadState threadState, MutableLoopData mutableData,
22902331
PythonContext.TraceEvent event, int line, boolean useLocalFn) {
22912332
if (threadState.isTracing()) {

0 commit comments

Comments
 (0)