158
158
import com .oracle .graal .python .nodes .frame .WriteGlobalNodeGen ;
159
159
import com .oracle .graal .python .nodes .frame .WriteNameNode ;
160
160
import com .oracle .graal .python .nodes .frame .WriteNameNodeGen ;
161
+ import com .oracle .graal .python .nodes .object .GetClassNode ;
161
162
import com .oracle .graal .python .nodes .object .IsNode ;
162
163
import com .oracle .graal .python .nodes .statement .ExceptNode .ExceptMatchNode ;
163
164
import com .oracle .graal .python .nodes .statement .ExceptNodeFactory .ExceptMatchNodeGen ;
@@ -497,9 +498,7 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod
497
498
@ Child private CalleeContext calleeContext = CalleeContext .create ();
498
499
@ Child private PythonObjectFactory factory = PythonObjectFactory .create ();
499
500
@ Child private ExceptionStateNodes .GetCaughtExceptionNode getCaughtExceptionNode ;
500
- // private GetExceptionTracebackNode traceGetExceptionTracebackNode = null;
501
- private MaterializeFrameNode traceMaterializeFrameNode = null ;
502
- // private CallTernaryMethodNode traceCallTernaryMethodNode = null;
501
+ @ Child private MaterializeFrameNode traceMaterializeFrameNode = null ;
503
502
504
503
private final LoopConditionProfile exceptionChainProfile1 = LoopConditionProfile .createCountingProfile ();
505
504
private final LoopConditionProfile exceptionChainProfile2 = LoopConditionProfile .createCountingProfile ();
@@ -1107,14 +1106,11 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
1107
1106
CompilerAsserts .partialEvaluationConstant (bci );
1108
1107
CompilerAsserts .partialEvaluationConstant (stackTop );
1109
1108
1110
- if (!noTrace .isValid () && threadState .getTraceFun () != null && !threadState .isTracing ()) {
1111
- mutableData .pyFrame = ensurePyFrame (virtualFrame , null );
1112
- // if we are simply continuing to run an OSR loop after the replacememnt, tracing an
1113
- // extra CALL event would be incorrect
1114
- if (!fromOSR ) {
1115
- mutableData .pyFrame .setLocalTraceFun (invokeTraceFunction (threadState .getTraceFun (), null , threadState , virtualFrame , mutableData .pyFrame , PythonContext .TraceEvent .CALL ,
1116
- initialBci == 0 ? getFirstLineno () : (mutableData .pastLine = bciToLine (initialBci ))));
1117
- }
1109
+ // if we are simply continuing to run an OSR loop after the replacement, tracing an
1110
+ // extra CALL event would be incorrect
1111
+ if (!noTrace .isValid () && threadState .getTraceFun () != null && !fromOSR ) {
1112
+ invokeTraceFunction (virtualFrame , null , threadState , mutableData , PythonContext .TraceEvent .CALL ,
1113
+ initialBci == 0 ? getFirstLineno () : (mutableData .pastLine = bciToLine (initialBci )), false );
1118
1114
}
1119
1115
1120
1116
mutableData .returnLine = mutableData .pastLine ;
@@ -1124,8 +1120,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
1124
1120
while (true ) {
1125
1121
final byte bc = localBC [bci ];
1126
1122
final int beginBci = bci ;
1127
- if (!noTrace .isValid () && threadState .getTraceFun () != null && !threadState .isTracing ()) {
1128
- mutableData .pyFrame = ensurePyFrame (virtualFrame , mutableData .pyFrame );
1123
+ if (!noTrace .isValid () && threadState .getTraceFun () != null ) {
1129
1124
int thisLine = bciToLine (bci );
1130
1125
boolean onANewLine = thisLine != mutableData .pastLine ;
1131
1126
mutableData .pastLine = thisLine ;
@@ -1147,22 +1142,21 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
1147
1142
* https://github.com/python/cpython/blob/main/Objects/lnotab_notes.txt#L210-L215
1148
1143
* for more details
1149
1144
*/
1150
- boolean shouldTrace = mutableData .pyFrame .getLocalTraceFun () != null && mutableData .pyFrame .getTraceLine ();
1151
- if (shouldTrace ) {
1152
- shouldTrace = mutableData .pastBci > bci ; // is a backward jump
1153
- if (!shouldTrace ) {
1154
- shouldTrace = onANewLine &&
1155
- // is not a forward jump
1156
- (mutableData .pastBci + c .length () >= bci ||
1157
- // is a forward jump to the start of line
1158
- bciToLine (bci - 1 ) != thisLine );
1159
- }
1145
+ boolean shouldTrace = mutableData .pastBci > bci ; // is a backward jump
1146
+ if (!shouldTrace ) {
1147
+ shouldTrace = onANewLine &&
1148
+ // is not a forward jump
1149
+ (mutableData .pastBci + c .length () >= bci ||
1150
+ // is a forward jump to the start of line
1151
+ bciToLine (bci - 1 ) != thisLine );
1160
1152
}
1161
1153
if (shouldTrace ) {
1162
1154
mutableData .returnLine = mutableData .pastLine ;
1163
- mutableData .pyFrame .setLocalTraceFun (
1164
- invokeTraceFunction (mutableData .pyFrame .getLocalTraceFun (), null , threadState , virtualFrame , mutableData .pyFrame , PythonContext .TraceEvent .LINE ,
1165
- mutableData .pastLine ));
1155
+ mutableData .pyFrame = ensurePyFrame (virtualFrame , mutableData .pyFrame );
1156
+ if (mutableData .pyFrame .getTraceLine ()) {
1157
+ invokeTraceFunction (virtualFrame , null , threadState , mutableData , PythonContext .TraceEvent .LINE ,
1158
+ mutableData .pastLine , true );
1159
+ }
1166
1160
}
1167
1161
}
1168
1162
if (!noTrace .isValid () && threadState .getTraceFun () != null ) {
@@ -1622,12 +1616,9 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
1622
1616
LoopNode .reportLoopCount (this , mutableData .loopCount );
1623
1617
}
1624
1618
Object value = virtualFrame .getObject (stackTop );
1625
- if (!noTrace .isValid () && threadState .getTraceFun () != null && !threadState .isTracing ()) {
1626
- mutableData .pyFrame = ensurePyFrame (virtualFrame , mutableData .pyFrame );
1627
- if (mutableData .pyFrame .getLocalTraceFun () != null ) {
1628
- invokeTraceFunction (mutableData .pyFrame .getLocalTraceFun (), value , threadState , virtualFrame , mutableData .pyFrame , PythonContext .TraceEvent .RETURN ,
1629
- mutableData .pyFrame .getTraceLine () ? mutableData .returnLine : bciToLine (bci ));
1630
- }
1619
+ if (!noTrace .isValid () && threadState .getTraceFun () != null ) {
1620
+ invokeTraceFunction (virtualFrame , value , threadState , mutableData , PythonContext .TraceEvent .RETURN ,
1621
+ mutableData .returnLine , true );
1631
1622
}
1632
1623
if (isGeneratorOrCoroutine ) {
1633
1624
throw new GeneratorReturnException (value );
@@ -2067,12 +2058,9 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
2067
2058
// Clear slots that were popped (if any)
2068
2059
clearFrameSlots (localFrame , stackTop + 1 , initialStackTop );
2069
2060
}
2070
- if (!noTrace .isValid () && threadState .getTraceFun () != null && !threadState .isTracing ()) {
2071
- mutableData .pyFrame = ensurePyFrame (virtualFrame , mutableData .pyFrame );
2072
- if (mutableData .pyFrame .getLocalTraceFun () != null ) {
2073
- invokeTraceFunction (mutableData .pyFrame .getLocalTraceFun (), value , threadState , virtualFrame , mutableData .pyFrame , PythonContext .TraceEvent .RETURN ,
2074
- mutableData .pyFrame .getTraceLine () ? mutableData .returnLine : bciToLine (bci ));
2075
- }
2061
+ if (!noTrace .isValid () && threadState .getTraceFun () != null ) {
2062
+ invokeTraceFunction (virtualFrame , value , threadState , mutableData , PythonContext .TraceEvent .RETURN ,
2063
+ mutableData .returnLine , true );
2076
2064
}
2077
2065
return new GeneratorYieldResult (bci + 1 , stackTop , value );
2078
2066
}
@@ -2165,10 +2153,12 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
2165
2153
mutableData .pyFrame = ensurePyFrame (virtualFrame , mutableData .pyFrame );
2166
2154
if (mutableData .pyFrame .getLocalTraceFun () != null ) {
2167
2155
Object traceback = GetExceptionTracebackNode .getUncached ().execute (pe );
2168
- mutableData .pyFrame .setLocalTraceFun (invokeTraceFunction (mutableData .pyFrame .getLocalTraceFun (),
2169
- factory .createTuple (new Object []{pe .getClass (), pe .setCatchingFrameAndGetEscapedException (virtualFrame , this ), traceback }), threadState , virtualFrame ,
2170
- mutableData .pyFrame ,
2171
- PythonContext .TraceEvent .EXCEPTION , bciToLine (bci )));
2156
+ PBaseException peForPython = pe .setCatchingFrameAndGetEscapedException (virtualFrame , this );
2157
+ Object peType = GetClassNode .getUncached ().execute (peForPython );
2158
+ invokeTraceFunction (virtualFrame ,
2159
+ factory .createTuple (new Object []{peType , peForPython , traceback }), threadState ,
2160
+ mutableData ,
2161
+ PythonContext .TraceEvent .EXCEPTION , bciToLine (bci ), true );
2172
2162
}
2173
2163
}
2174
2164
@@ -2201,11 +2191,8 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod
2201
2191
LoopNode .reportLoopCount (this , mutableData .loopCount );
2202
2192
}
2203
2193
if (!noTrace .isValid () && threadState .getTraceFun () != null ) {
2204
- mutableData .pyFrame = ensurePyFrame (virtualFrame , mutableData .pyFrame );
2205
- if (mutableData .pyFrame .getLocalTraceFun () != null ) {
2206
- invokeTraceFunction (mutableData .pyFrame .getLocalTraceFun (), PNone .NONE , threadState , virtualFrame , mutableData .pyFrame , PythonContext .TraceEvent .RETURN ,
2207
- mutableData .pyFrame .getTraceLine () ? mutableData .returnLine : bciToLine (bci ));
2208
- }
2194
+ invokeTraceFunction (virtualFrame , PNone .NONE , threadState , mutableData , PythonContext .TraceEvent .RETURN ,
2195
+ mutableData .returnLine , true );
2209
2196
}
2210
2197
if (e == pe ) {
2211
2198
throw pe ;
@@ -2243,22 +2230,32 @@ private PFrame ensurePyFrame(VirtualFrame virtualFrame, PFrame pyFrame) {
2243
2230
}
2244
2231
2245
2232
@ HostCompilerDirectives .InliningCutoff
2246
- private Object invokeTraceFunction (Object traceFn , Object arg , PythonContext .PythonThreadState threadState , VirtualFrame virtualFrame , PFrame tracing ,
2247
- PythonContext .TraceEvent event , int line ) {
2233
+ private void invokeTraceFunction (VirtualFrame virtualFrame , Object arg , PythonContext .PythonThreadState threadState , MutableLoopData mutableData ,
2234
+ PythonContext .TraceEvent event , int line , boolean useLocalFn ) {
2235
+ if (threadState .isTracing ()) {
2236
+ return ;
2237
+ }
2248
2238
threadState .tracingStart (event );
2239
+ PFrame pyFrame = mutableData .pyFrame = ensurePyFrame (virtualFrame , mutableData .pyFrame );
2240
+ Object traceFn = useLocalFn ? pyFrame .getLocalTraceFun () : threadState .getTraceFun ();
2241
+ if (traceFn == null ) {
2242
+ threadState .tracingStop ();
2243
+ return ;
2244
+ }
2249
2245
Object nonNullArg = arg == null ? PNone .NONE : arg ;
2250
2246
try {
2251
2247
if (line != -1 ) {
2252
- tracing .setLineLock (line );
2248
+ pyFrame .setLineLock (line );
2253
2249
}
2254
- Object result = CallTernaryMethodNode .getUncached ().execute (null , traceFn , tracing , event .pythonName , nonNullArg );
2255
- return result == PNone .NONE ? null : result ;
2250
+ Object result = CallTernaryMethodNode .getUncached ().execute (null , traceFn , pyFrame , event .pythonName , nonNullArg );
2251
+ Object realResult = result == PNone .NONE ? null : result ;
2252
+ pyFrame .setLocalTraceFun (realResult );
2256
2253
} catch (Throwable e ) {
2257
2254
threadState .setTraceFun (null , cachedLanguage );
2258
2255
throw e ;
2259
2256
} finally {
2260
2257
if (line != -1 ) {
2261
- tracing .lineUnlock ();
2258
+ pyFrame .lineUnlock ();
2262
2259
}
2263
2260
threadState .tracingStop ();
2264
2261
}
0 commit comments