Skip to content

Commit 4956ef3

Browse files
committed
Replace PFrame.stale with PFrame.lastCallerFlags
1 parent 718251c commit 4956ef3

File tree

6 files changed

+43
-24
lines changed

6 files changed

+43
-24
lines changed

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

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,11 @@ public final class PFrame extends PythonBuiltinObject {
103103

104104
private PFrame.Reference backref = null;
105105

106-
// Whether lasti and locals are stale, see isStale
107-
private boolean stale;
106+
/**
107+
* The last {@link CallerFlags} that were used the last time the frame was synced or passed down
108+
* to a callee. See {@link #isStale(VirtualFrame, int)} for more details.
109+
*/
110+
private int lastCallerFlags;
108111

109112
public Object getLocalTraceFun() {
110113
return localTraceFun;
@@ -200,6 +203,9 @@ public PFrame(PythonLanguage lang, Reference virtualFrameInfo, Node location, bo
200203
this.virtualFrameInfo = virtualFrameInfo;
201204
this.location = location;
202205
this.hasCustomLocals = hasCustomLocals;
206+
// Mark everything as current for now. MaterializeFrameNode will set lastCallerFlags to a
207+
// narrower value if needed
208+
this.lastCallerFlags = CallerFlags.ALL_FRAME_FLAGS;
203209
}
204210

205211
public PFrame(PythonLanguage lang, @SuppressWarnings("unused") Object threadState, PCode code, PythonObject globals, Object localsDict) {
@@ -216,18 +222,21 @@ public PFrame(PythonLanguage lang, @SuppressWarnings("unused") Object threadStat
216222
this.arguments = frameArgs;
217223
this.hasCustomLocals = true;
218224
this.localsDict = localsDict;
225+
// This is a synthetic frame, there will be no sync, mark everything as current
226+
this.lastCallerFlags = CallerFlags.ALL_FRAME_FLAGS;
219227
}
220228

221229
/**
222230
* Get the locals synced by {@link MaterializeFrameNode}. May be null when using custom locals.
223231
* In most cases, you should use {@link GetFrameLocalsNode}.
224232
*/
225233
public MaterializedFrame getLocals() {
226-
assert !stale;
234+
assert CallerFlags.needsLocals(lastCallerFlags) : "Missing frame locals sync";
227235
return locals;
228236
}
229237

230238
public void setLocals(MaterializedFrame locals) {
239+
lastCallerFlags |= CallerFlags.NEEDS_LOCALS;
231240
this.locals = locals;
232241
}
233242

@@ -245,15 +254,23 @@ public void setLocals(MaterializedFrame locals) {
245254
* flags from {@link CallerFlags}.
246255
*/
247256
public boolean isStale(VirtualFrame frame, int callerFlags) {
248-
boolean needsLocals = CallerFlags.needsLocals(callerFlags) && !hasCustomLocals;
249-
if (needsLocals && locals == null) {
257+
if (hasCustomLocals) {
258+
// Custom locals don't need locals sync
259+
callerFlags &= ~CallerFlags.NEEDS_LOCALS;
260+
}
261+
if (CallerFlags.needsLocals(callerFlags) && locals == null) {
250262
return true;
251263
}
252-
return (CallerFlags.needsLasti(callerFlags) || needsLocals) && (stale || (frame != null && PArguments.getCurrentFrameInfo(frame) == getRef()));
264+
if (CallerFlags.needsLocals(callerFlags) || CallerFlags.needsLasti(callerFlags)) {
265+
if (frame != null && PArguments.getCurrentFrameInfo(frame) == getRef()) {
266+
return true;
267+
}
268+
}
269+
return (callerFlags & lastCallerFlags) != callerFlags;
253270
}
254271

255-
public void setStale(boolean stale) {
256-
this.stale = stale;
272+
public void setLastCallerFlags(int lastCallerFlags) {
273+
this.lastCallerFlags = lastCallerFlags;
257274
}
258275

259276
/**
@@ -309,17 +326,16 @@ public boolean didJump() {
309326

310327
@TruffleBoundary
311328
public int getLine() {
312-
assert !stale;
313329
if (line == UNINITIALIZED_LINE) {
314330
if (location == null) {
315331
line = -1;
316332
} else if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
317333
if (location instanceof BytecodeNode bytecodeNode) {
318334
PBytecodeDSLRootNode rootNode = (PBytecodeDSLRootNode) bytecodeNode.getRootNode();
319-
return rootNode.bciToLine(bci, bytecodeNode);
335+
return rootNode.bciToLine(getBci(), bytecodeNode);
320336
}
321337
} else if (location instanceof PBytecodeRootNode bytecodeRootNode) {
322-
return bytecodeRootNode.bciToLine(bci);
338+
return bytecodeRootNode.bciToLine(getBci());
323339
}
324340
}
325341
return line;
@@ -374,10 +390,12 @@ public int getBci() {
374390
}
375391

376392
public void setBci(int bci) {
393+
this.lastCallerFlags |= CallerFlags.NEEDS_LASTI;
377394
this.bci = bci;
378395
}
379396

380397
public int getLasti() {
398+
assert CallerFlags.needsLasti(lastCallerFlags) : "Missing frame location sync";
381399
return bciToLasti(bci, location);
382400
}
383401

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ static Object doLoop(VirtualFrame frame, Node inliningTarget, PFrame pyFrame, bo
107107
if (!freshFrame && pyFrame.isStale(frame, CallerFlags.NEEDS_LOCALS)) {
108108
pyFrame = readFrameNode.refreshFrame(frame, pyFrame.getRef(), CallerFlags.NEEDS_LOCALS);
109109
}
110+
assert !pyFrame.isStale(null, CallerFlags.NEEDS_LOCALS);
110111
MaterializedFrame locals = pyFrame.getLocals();
111112
// It doesn't have custom locals, so it has to be a builtin dict or null
112113
PDict localsDict = (PDict) pyFrame.getLocalsDict();

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

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import com.oracle.graal.python.nodes.bytecode.BytecodeFrameInfo;
5151
import com.oracle.graal.python.nodes.bytecode.FrameInfo;
5252
import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode;
53+
import com.oracle.graal.python.runtime.CallerFlags;
5354
import com.oracle.graal.python.runtime.PythonOptions;
5455
import com.oracle.graal.python.runtime.object.PFactory;
5556
import com.oracle.truffle.api.CompilerAsserts;
@@ -190,12 +191,9 @@ static PFrame freshPFrameForGenerator(Node location, @SuppressWarnings("unused")
190191
static PFrame alreadyEscapedFrame(@SuppressWarnings("unused") Node location, boolean markAsEscaped, boolean forceSync, Frame frameToMaterialize,
191192
@Shared("syncValuesNode") @Cached SyncFrameValuesNode syncValuesNode) {
192193
PFrame pyFrame = getPFrame(frameToMaterialize);
193-
pyFrame.setStale(false);
194+
pyFrame.setLastCallerFlags(getCallerFlags(forceSync));
194195
if (forceSync) {
195196
syncValuesNode.execute(pyFrame, frameToMaterialize, location);
196-
} else {
197-
// Clear stale locals
198-
pyFrame.setLocals(null);
199197
}
200198
if (markAsEscaped) {
201199
pyFrame.getRef().markAsEscaped();
@@ -244,12 +242,9 @@ private static PFrame doEscapeFrame(Frame frameToMaterialize, PFrame escapedFram
244242

245243
// on a freshly created PFrame, we do always sync the arguments
246244
PArguments.synchronizeArgs(frameToMaterialize, escapedFrame);
247-
escapedFrame.setStale(false);
245+
escapedFrame.setLastCallerFlags(getCallerFlags(forceSync));
248246
if (forceSync) {
249247
syncValuesNode.execute(escapedFrame, frameToMaterialize, location);
250-
} else {
251-
// Clear stale locals
252-
escapedFrame.setLocals(null);
253248
}
254249
if (markAsEscaped) {
255250
topFrameRef.markAsEscaped();
@@ -258,6 +253,10 @@ private static PFrame doEscapeFrame(Frame frameToMaterialize, PFrame escapedFram
258253
return escapedFrame;
259254
}
260255

256+
private static int getCallerFlags(boolean forceSync) {
257+
return CallerFlags.NEEDS_FRAME_REFERENCE | CallerFlags.NEEDS_PFRAME | CallerFlags.NEEDS_LASTI | (forceSync ? CallerFlags.NEEDS_LOCALS : 0);
258+
}
259+
261260
protected static boolean hasCustomLocals(Frame frame) {
262261
return PArguments.getSpecialArgument(frame) != null;
263262
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public abstract class CallerFlags {
5858
*/
5959
public static final int NEEDS_LASTI = 1 << 4;
6060

61+
public static final int ALL_FRAME_FLAGS = NEEDS_FRAME_REFERENCE | NEEDS_PFRAME | NEEDS_LOCALS | NEEDS_LASTI;
62+
6163
public static boolean needsExceptionState(int callerFlags) {
6264
return (callerFlags & NEEDS_EXCEPTION_STATE) != 0;
6365
}

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,14 @@ protected static void passCallerFrame(VirtualFrame frame, Object[] callArguments
228228
assert materialize.isAdoptable();
229229
}
230230
if (thisInfo.getPyFrame() != null && !CallerFlags.needsLocals(callerFlags) && !CallerFlags.needsLasti(callerFlags)) {
231-
thisInfo.getPyFrame().setStale(true);
231+
thisInfo.getPyFrame().setLastCallerFlags(callerFlags);
232232
} else {
233233
PFrame pyFrame = materialize.executeOnStack(false, CallerFlags.needsLocals(callerFlags), frame);
234234
assert thisInfo.getPyFrame() == pyFrame;
235235
assert pyFrame.getRef() == thisInfo;
236236
}
237237
} else if (thisInfo.getPyFrame() != null) {
238-
thisInfo.getPyFrame().setStale(true);
238+
thisInfo.getPyFrame().setLastCallerFlags(callerFlags);
239239
}
240240
PArguments.setCallerFrameInfo(callArguments, thisInfo);
241241
}
@@ -712,8 +712,7 @@ private static Object enterSlowPath(VirtualFrame frame, IndirectCallDataBase cal
712712
if (CallerFlags.needsPFrame(callerFlags)) {
713713
callData.getMaterializeFrameNode().executeOnStack(false, CallerFlags.needsLocals(callerFlags), frame);
714714
} else if (info.getPyFrame() != null) {
715-
// Avoid passing stale locals
716-
info.getPyFrame().setStale(true);
715+
info.getPyFrame().setLastCallerFlags(callerFlags);
717716
}
718717
}
719718
AbstractTruffleException curExc = pythonThreadState.getCaughtException();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public int getCallerFlags() {
132132

133133
@TruffleBoundary
134134
public void updateCallerFlags(int newFlags) {
135-
if ((newFlags & CallerFlags.NEEDS_LOCALS) != 0) {
135+
if ((newFlags & (CallerFlags.NEEDS_LOCALS | CallerFlags.NEEDS_LASTI)) != 0) {
136136
newFlags |= CallerFlags.NEEDS_PFRAME;
137137
}
138138
if ((newFlags & CallerFlags.NEEDS_PFRAME) != 0) {

0 commit comments

Comments
 (0)