Skip to content

Commit 99721de

Browse files
committed
Fix locations for bytecode interpreter
1 parent f06d0f2 commit 99721de

File tree

5 files changed

+60
-60
lines changed

5 files changed

+60
-60
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/FrameBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ Object getUpdating(VirtualFrame frame, PFrame self,
303303
// frame. If 'self' represents another frame on the stack, the values are already
304304
// refreshed.
305305
if (profile.profile(inliningTarget, frame != null && PArguments.getCurrentFrameInfo(frame) == self.getRef())) {
306-
PFrame pyFrame = materializeNode.execute(false, true, frame);
306+
PFrame pyFrame = materializeNode.executeOnStack(false, true, frame);
307307
assert pyFrame == self;
308308
}
309309
return getFrameLocalsNode.execute(inliningTarget, self);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/traceback/TracebackBuiltins.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,12 +264,12 @@ static PFrame doOnStack(VirtualFrame frame, PTraceback tb,
264264

265265
// case 2.1: the frame info refers to the current frame
266266
if (isCurFrameProfile.profile(inliningTarget, PArguments.getCurrentFrameInfo(frame) == frameInfo)) {
267-
// materialize the current frame; marking is not necessary (already done);
268-
// refreshing
269-
// values is also not necessary (will be done on access to the locals or when
270-
// returning
271-
// from the frame)
272-
escapedFrame = materializeNode.execute(frame, false);
267+
/*
268+
* materialize the current frame; marking is not necessary (already done);
269+
* refreshing values is also not necessary (will be done on access to the locals or
270+
* when returning from the frame)
271+
*/
272+
escapedFrame = materializeNode.executeOnStack(false, false, frame);
273273
} else {
274274
// case 2.2: the frame info does not refer to the current frame
275275
for (int i = 0;; i++) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/MaterializeFrameNode.java

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -85,22 +85,17 @@ public static MaterializeFrameNode getUncached() {
8585
return MaterializeFrameNodeGen.getUncached();
8686
}
8787

88-
public final PFrame execute(boolean markAsEscaped, Frame frameToMaterialize) {
89-
return execute(markAsEscaped, false, frameToMaterialize);
88+
public final PFrame execute(Frame frame, Node location, boolean markAsEscaped, boolean forceSync) {
89+
return execute(location, markAsEscaped, forceSync, frame);
9090
}
9191

92-
public final PFrame execute(boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize) {
92+
public final PFrame executeOnStack(boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize) {
9393
PFrame.Reference info = PArguments.getCurrentFrameInfo(frameToMaterialize);
94-
Node rootNode = info.getRootNode();
95-
return execute(rootNode, markAsEscaped, forceSync, frameToMaterialize);
96-
}
97-
98-
public final PFrame execute(Frame frame, boolean markAsEscaped) {
99-
return execute(markAsEscaped, frame);
100-
}
101-
102-
public final PFrame execute(Frame frame, Node location, boolean markAsEscaped, boolean forceSync) {
103-
return execute(location, markAsEscaped, forceSync, frame);
94+
Node location = info.getRootNode();
95+
if (location instanceof PBytecodeDSLRootNode rootNode) {
96+
location = rootNode.getBytecodeNode();
97+
}
98+
return execute(location, markAsEscaped, forceSync, frameToMaterialize);
10499
}
105100

106101
public abstract PFrame execute(Node location, boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize);
@@ -180,10 +175,9 @@ private static void processBytecodeFrame(Frame frameToMaterialize, PFrame pyFram
180175
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
181176
BytecodeNode bytecodeNode = BytecodeNode.get(location);
182177
if (bytecodeNode == null) {
183-
/**
184-
* Sometimes we don't have a precise location (see
185-
* {@link ReadCallerFrameNode#getFrame}). Set bci to -1 to mark the location as
186-
* unknown.
178+
/*
179+
* Sometimes we don't have a precise location (see {@link
180+
* ReadCallerFrameNode#getFrame}). Set bci to -1 to mark the location as unknown.
187181
*/
188182
pyFrame.setBci(-1);
189183
pyFrame.setLocation(location);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadCallerFrameNode.java

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import com.oracle.graal.python.builtins.objects.frame.PFrame;
4646
import com.oracle.graal.python.builtins.objects.function.PArguments;
4747
import com.oracle.graal.python.nodes.PRootNode;
48+
import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode;
4849
import com.oracle.graal.python.runtime.IndirectCallData;
4950
import com.oracle.truffle.api.CompilerDirectives;
5051
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
@@ -156,42 +157,42 @@ public PFrame executeWith(PFrame.Reference startFrameInfo, FrameInstance.FrameAc
156157
for (int i = 0; i <= level;) {
157158
PFrame.Reference callerInfo = curFrameInfo.getCallerInfo();
158159
if (callerInfo == null) {
159-
Frame callerFrame = getCallerFrame(startFrameInfo, frameAccess, selector, level);
160-
if (callerFrame != null) {
161-
return ensureMaterializeNode().execute(false, true, callerFrame);
162-
}
163-
return null;
160+
return getMaterializedCallerFrame(startFrameInfo, frameAccess, selector, level);
164161
} else if (!selector.skip(callerInfo.getRootNode())) {
165162
i++;
166163
}
167164
curFrameInfo = callerInfo;
168165
}
166+
return curFrameInfo.getPyFrame();
169167
} else {
170-
curFrameInfo = walkLevels(curFrameInfo, frameAccess, selector, level);
168+
return walkLevels(curFrameInfo, frameAccess, selector, level);
169+
}
170+
}
171+
172+
private PFrame getMaterializedCallerFrame(PFrame.Reference startFrameInfo, FrameInstance.FrameAccess frameAccess, FrameSelector selector, int level) {
173+
StackWalkResult callerFrameResult = getCallerFrame(startFrameInfo, frameAccess, selector, level);
174+
if (callerFrameResult != null) {
175+
Node location = callerFrameResult.rootNode;
176+
if (location instanceof PBytecodeDSLRootNode rootNode) {
177+
location = rootNode.getBytecodeNode();
178+
}
179+
return ensureMaterializeNode().execute(location, false, true, callerFrameResult.frame);
171180
}
172-
return curFrameInfo.getPyFrame();
181+
return null;
173182
}
174183

175-
private PFrame.Reference walkLevels(PFrame.Reference startFrameInfo, FrameInstance.FrameAccess frameAccess, FrameSelector selector, int level) {
184+
private PFrame walkLevels(PFrame.Reference startFrameInfo, FrameInstance.FrameAccess frameAccess, FrameSelector selector, int level) {
176185
PFrame.Reference currentFrame = startFrameInfo;
177186
for (int i = 0; i <= level;) {
178187
PFrame.Reference callerInfo = currentFrame.getCallerInfo();
179188
if (cachedCallerFrameProfile.profile(callerInfo == null || callerInfo.getPyFrame() == null)) {
180-
Frame callerFrame = getCallerFrame(startFrameInfo, frameAccess, selector, level);
181-
if (callerFrame != null) {
182-
// At this point, we must 'materialize' the frame. Actually, the Truffle frame
183-
// is never materialized but we ensure that a corresponding PFrame is created
184-
// and that the locals and arguments are synced.
185-
ensureMaterializeNode().execute(false, true, callerFrame);
186-
return PArguments.getCurrentFrameInfo(callerFrame);
187-
}
188-
return PFrame.Reference.EMPTY;
189+
return getMaterializedCallerFrame(startFrameInfo, frameAccess, selector, level);
189190
} else if (!selector.skip(callerInfo.getRootNode())) {
190191
i++;
191192
}
192193
currentFrame = callerInfo;
193194
}
194-
return currentFrame;
195+
return currentFrame.getPyFrame();
195196
}
196197

197198
/**
@@ -258,7 +259,11 @@ private PFrame.Reference walkLevels(PFrame.Reference startFrameInfo, FrameInstan
258259
* @param frameAccess - the desired {@link FrameInstance} access kind
259260
*/
260261
public static Frame getCurrentFrame(Node requestingNode, FrameInstance.FrameAccess frameAccess) {
261-
return getFrame(Objects.requireNonNull(requestingNode), null, frameAccess, AllFramesSelector.INSTANCE, 0);
262+
StackWalkResult result = getFrame(Objects.requireNonNull(requestingNode), null, frameAccess, AllFramesSelector.INSTANCE, 0);
263+
if (result != null) {
264+
return result.frame;
265+
}
266+
return null;
262267
}
263268

264269
/**
@@ -272,14 +277,17 @@ public static Frame getCurrentFrame(Node requestingNode, FrameInstance.FrameAcce
272277
* @param selector - declares which frames should be skipped or counted
273278
* @param level - the stack depth to go to. Ignored if {@code startFrame} is {@code null}
274279
*/
275-
public static Frame getCallerFrame(PFrame.Reference startFrame, FrameInstance.FrameAccess frameAccess, FrameSelector selector, int level) {
280+
public static StackWalkResult getCallerFrame(PFrame.Reference startFrame, FrameInstance.FrameAccess frameAccess, FrameSelector selector, int level) {
276281
CompilerDirectives.transferToInterpreterAndInvalidate();
277282
return getFrame(null, Objects.requireNonNull(startFrame), frameAccess, selector, level);
278283
}
279284

285+
public record StackWalkResult(PRootNode rootNode, Frame frame) {
286+
}
287+
280288
@TruffleBoundary
281-
private static Frame getFrame(Node requestingNode, PFrame.Reference startFrame, FrameInstance.FrameAccess frameAccess, FrameSelector selector, int level) {
282-
Frame[] outputFrame = new Frame[1];
289+
private static StackWalkResult getFrame(Node requestingNode, PFrame.Reference startFrame, FrameInstance.FrameAccess frameAccess, FrameSelector selector, int level) {
290+
StackWalkResult[] result = new StackWalkResult[1];
283291
Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<>() {
284292
int i = -1;
285293

@@ -288,8 +296,8 @@ private static Frame getFrame(Node requestingNode, PFrame.Reference startFrame,
288296
* associated with it may have been called from a different language, and thus not be
289297
* able to pass the caller frame. That means that we cannot immediately return when we
290298
* find the correct level frame, but instead we need to remember the frame in
291-
* {@code outputFrame} and then keep going until we find the previous Python caller on
292-
* the stack (or not). That last Python caller should have {@link IndirectCallData} that
299+
* {@code result} and then keep going until we find the previous Python caller on the
300+
* stack (or not). That last Python caller should have {@link IndirectCallData} that
293301
* will be marked to pass the frame through the context.
294302
*
295303
* <pre>
@@ -308,13 +316,13 @@ private static Frame getFrame(Node requestingNode, PFrame.Reference startFrame,
308316
* ================
309317
* </pre>
310318
*/
311-
public Frame visitFrame(FrameInstance frameInstance) {
319+
public StackWalkResult visitFrame(FrameInstance frameInstance) {
312320
RootNode rootNode = getRootNode(frameInstance);
313321
Node callNode = frameInstance.getCallNode();
314322
boolean didMark = IndirectCallData.setEncapsulatingNeedsToPassCallerFrame(callNode != null ? callNode : requestingNode);
315323
if (rootNode instanceof PRootNode pRootNode && pRootNode.setsUpCalleeContext()) {
316-
if (outputFrame[0] != null) {
317-
return outputFrame[0];
324+
if (result[0] != null) {
325+
return result[0];
318326
}
319327
boolean needsCallerFrame = true;
320328
if (i < 0 && startFrame != null) {
@@ -329,7 +337,7 @@ public Frame visitFrame(FrameInstance frameInstance) {
329337
if (i == level || startFrame == null) {
330338
Frame frame = getFrame(frameInstance, frameAccess);
331339
assert PArguments.isPythonFrame(frame);
332-
outputFrame[0] = frame;
340+
result[0] = new StackWalkResult(pRootNode, frame);
333341
needsCallerFrame = false;
334342
}
335343
i += 1;
@@ -340,13 +348,13 @@ public Frame visitFrame(FrameInstance frameInstance) {
340348
}
341349
}
342350
if (didMark) {
343-
return outputFrame[0];
351+
return result[0];
344352
} else {
345353
return null;
346354
}
347355
}
348356
});
349-
return outputFrame[0];
357+
return result[0];
350358
}
351359

352360
private static RootNode getRootNode(FrameInstance frameInstance) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.oracle.graal.python.nodes.frame.MaterializeFrameNode;
5151
import com.oracle.graal.python.nodes.frame.MaterializeFrameNodeGen;
5252
import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode;
53+
import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode.StackWalkResult;
5354
import com.oracle.graal.python.nodes.util.ExceptionStateNodes.GetCaughtExceptionNode;
5455
import com.oracle.graal.python.runtime.ExecutionContextFactory.CallContextNodeGen;
5556
import com.oracle.graal.python.runtime.PythonContext.PythonThreadState;
@@ -71,7 +72,6 @@
7172
import com.oracle.truffle.api.dsl.ReportPolymorphism;
7273
import com.oracle.truffle.api.dsl.Specialization;
7374
import com.oracle.truffle.api.exception.AbstractTruffleException;
74-
import com.oracle.truffle.api.frame.Frame;
7575
import com.oracle.truffle.api.frame.FrameInstance;
7676
import com.oracle.truffle.api.frame.MaterializedFrame;
7777
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -327,12 +327,10 @@ private void exitEscaped(VirtualFrame frame, PRootNode node, Node location, Refe
327327
// n.b. We need to use 'ReadCallerFrameNode.getCallerFrame' instead of
328328
// 'Truffle.getRuntime().getCallerFrame()' because we still need to skip
329329
// non-Python frames, even if we do not skip frames of builtin functions.
330-
Frame callerFrame = ReadCallerFrameNode.getCallerFrame(info, FrameInstance.FrameAccess.READ_ONLY, ReadCallerFrameNode.AllFramesSelector.INSTANCE, 0);
331-
if (PArguments.isPythonFrame(callerFrame)) {
332-
callerInfo = PArguments.getCurrentFrameInfo(callerFrame);
330+
StackWalkResult callerFrameResult = ReadCallerFrameNode.getCallerFrame(info, FrameInstance.FrameAccess.READ_ONLY, ReadCallerFrameNode.AllFramesSelector.INSTANCE, 0);
331+
if (callerFrameResult != null) {
332+
callerInfo = PArguments.getCurrentFrameInfo(callerFrameResult.frame());
333333
} else {
334-
// TODO: frames: an assertion should be that this is one of our
335-
// entry point call nodes
336334
callerInfo = Reference.EMPTY;
337335
}
338336
// ReadCallerFrameNode.getCallerFrame must have the assumption invalidated

0 commit comments

Comments
 (0)