Skip to content

Commit e21e40e

Browse files
committed
Sync locals only when requested specifically
1 parent e7ecc4b commit e21e40e

34 files changed

+374
-346
lines changed

graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/Builtin.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@
7777
boolean needsFrame() default false;
7878

7979
/**
80-
* By default the caller frame bit is set on-demand, but for some builtins it might be useful to
81-
* always force passing the caller frame.
80+
* By default the callerFlags bits are set on-demand, but for some builtins it might be useful
81+
* to pre-set them.
8282
*/
83-
boolean alwaysNeedsCallerFrame() default false;
83+
int callerFlags() default 0;
8484

8585
/**
8686
* Module functions should be bound to their module, meaning they would take the module itself

graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/Slot.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
* The slot node either needs frame for execution (e.g., may call Python code) and/or is complex
5757
* enough that indirect call to partially evaluated code is preferred over uncached execution
5858
* without frame and without setting up indirect call context.
59-
*
59+
*
6060
* The slot call nodes AST inline slot nodes, but if the inline cache overflows or in the
6161
* uncached case, they need to either call uncached slot node or do indirect call if
6262
* {@code isComplex} is {@code true}.
@@ -97,7 +97,7 @@
9797

9898
boolean needsFrame() default false;
9999

100-
boolean alwaysNeedsCallerFrame() default false;
100+
int callerFlags() default 0;
101101
}
102102

103103
/** See <a href="https://docs.python.org/3/c-api/typeobj.html">slot documentation</a> */

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,6 @@ public ExecutableNode parse(InlineParsingRequest request) {
785785
@Override
786786
public Object execute(VirtualFrame frame) {
787787
Object[] arguments = PArguments.create();
788-
// escape?
789788
PFrame pFrame = materializeFrameNode.execute(this, false, true, frame);
790789
Object pLocals = getFrameLocalsNode.executeCached(pFrame);
791790
PArguments.setSpecialArgument(arguments, pLocals);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@
261261
import com.oracle.graal.python.pegparser.ParserCallbacks;
262262
import com.oracle.graal.python.pegparser.sst.ModTy;
263263
import com.oracle.graal.python.pegparser.tokenizer.SourceRange;
264+
import com.oracle.graal.python.runtime.CallerFlags;
264265
import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext;
265266
import com.oracle.graal.python.runtime.GilNode;
266267
import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData;
@@ -807,19 +808,20 @@ static Object[] inheritGlobals(VirtualFrame frame, Node inliningTarget, @Suppres
807808
@Exclusive @Cached ReadCallerFrameNode readCallerFrameNode,
808809
@Exclusive @Cached GetOrCreateDictNode getOrCreateDictNode,
809810
@Exclusive @Cached InlinedConditionProfile haveCallerFrameProfile,
810-
@Exclusive @Cached InlinedConditionProfile haveLocals,
811+
@Exclusive @Cached InlinedConditionProfile inheritLocalsProfile,
811812
@Exclusive @Cached PyMappingCheckNode mappingCheckNode,
812813
@Exclusive @Cached GetFrameLocalsNode getFrameLocalsNode,
813814
@Exclusive @Cached PRaiseNode raiseNode) {
814-
PFrame callerFrame = readCallerFrameNode.executeWith(frame, 0);
815+
boolean inheritLocals = inheritLocalsProfile.profile(inliningTarget, locals instanceof PNone);
816+
PFrame callerFrame = readCallerFrameNode.executeWith(frame, 0, inheritLocals);
815817
Object[] args = PArguments.create();
816818
boolean haveCallerFrame = haveCallerFrameProfile.profile(inliningTarget, callerFrame != null);
817819
if (haveCallerFrame) {
818820
PArguments.setGlobals(args, callerFrame.getGlobals());
819821
} else {
820822
PArguments.setGlobals(args, getOrCreateDictNode.execute(inliningTarget, PythonContext.get(inliningTarget).getMainModule()));
821823
}
822-
if (haveLocals.profile(inliningTarget, locals instanceof PNone)) {
824+
if (inheritLocals) {
823825
if (haveCallerFrame) {
824826
Object callerLocals = getFrameLocalsNode.execute(inliningTarget, callerFrame);
825827
setCustomLocals(args, callerLocals);
@@ -838,7 +840,7 @@ static Object[] inheritGlobals(VirtualFrame frame, Node inliningTarget, @Suppres
838840
@Specialization
839841
static Object[] customGlobals(VirtualFrame frame, Node inliningTarget, PDict globals, Object locals, TruffleString mode,
840842
@Bind PythonContext context,
841-
@Exclusive @Cached InlinedConditionProfile haveLocals,
843+
@Exclusive @Cached InlinedConditionProfile inheritLocalsProfile,
842844
@Exclusive @Cached PyMappingCheckNode mappingCheckNode,
843845
@Exclusive @Cached GetOrCreateDictNode getOrCreateDictNode,
844846
@Exclusive @Cached HashingCollectionNodes.SetItemNode setBuiltins,
@@ -851,7 +853,7 @@ static Object[] customGlobals(VirtualFrame frame, Node inliningTarget, PDict glo
851853
setBuiltins.execute(frame, inliningTarget, globals, T___BUILTINS__, builtinsDict);
852854
}
853855
PArguments.setGlobals(args, globals);
854-
if (haveLocals.profile(inliningTarget, locals instanceof PNone)) {
856+
if (inheritLocalsProfile.profile(inliningTarget, locals instanceof PNone)) {
855857
setCustomLocals(args, globals);
856858
} else {
857859
if (!mappingCheckNode.execute(inliningTarget, locals)) {
@@ -980,7 +982,7 @@ protected abstract Object executeInternal(VirtualFrame frame, Object source, Tru
980982
int featureVersion);
981983

982984
private int inheritFlags(VirtualFrame frame, int flags, ReadCallerFrameNode readCallerFrame) {
983-
PFrame fr = readCallerFrame.executeWith(frame, 0);
985+
PFrame fr = readCallerFrame.executeWith(frame, 0, false);
984986
if (fr != null) {
985987
PCode code = PFactory.createCode(PythonLanguage.get(this), fr.getTarget());
986988
flags |= code.getFlags() & PyCF_MASK;
@@ -2252,7 +2254,7 @@ private static long maybeInt(Node inliningTarget, InlinedConditionProfile result
22522254
}
22532255
}
22542256

2255-
@Builtin(name = "globals", needsFrame = true, alwaysNeedsCallerFrame = true)
2257+
@Builtin(name = "globals", needsFrame = true, callerFlags = CallerFlags.NEEDS_PFRAME)
22562258
@GenerateNodeFactory
22572259
abstract static class GlobalsNode extends PythonBuiltinNode {
22582260
private final ConditionProfile condProfile = ConditionProfile.create();
@@ -2271,7 +2273,7 @@ public Object globals(VirtualFrame frame,
22712273
}
22722274
}
22732275

2274-
@Builtin(name = "locals", needsFrame = true, alwaysNeedsCallerFrame = true)
2276+
@Builtin(name = "locals", needsFrame = true, callerFlags = CallerFlags.NEEDS_LOCALS)
22752277
@GenerateNodeFactory
22762278
abstract static class LocalsNode extends PythonBuiltinNode {
22772279

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@
230230
import com.oracle.graal.python.nodes.object.GetClassNode;
231231
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
232232
import com.oracle.graal.python.nodes.util.ExceptionStateNodes.GetCaughtExceptionNode;
233+
import com.oracle.graal.python.runtime.CallerFlags;
233234
import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext;
234235
import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData;
235236
import com.oracle.graal.python.runtime.PosixSupportLibrary;
@@ -855,7 +856,7 @@ static Object run(VirtualFrame frame,
855856
// ATTENTION: this is intentionally a PythonBuiltinNode and not PythonUnaryBuiltinNode,
856857
// because we need a guarantee that this builtin will get its own stack frame in order to
857858
// be able to count how many frames down the call stack we need to walk
858-
@Builtin(name = "_getframe", parameterNames = "depth", minNumOfPositionalArgs = 0, needsFrame = true, alwaysNeedsCallerFrame = true)
859+
@Builtin(name = "_getframe", parameterNames = "depth", minNumOfPositionalArgs = 0, needsFrame = true, callerFlags = CallerFlags.NEEDS_PFRAME)
859860
@ArgumentClinic(name = "depth", defaultValue = "0", conversion = ClinicConversion.Int)
860861
@GenerateNodeFactory
861862
public abstract static class GetFrameNode extends PythonClinicBuiltinNode {
@@ -880,7 +881,7 @@ static PFrame counted(VirtualFrame frame, int num,
880881
private static PFrame escapeFrame(VirtualFrame frame, int num, ReadCallerFrameNode readCallerNode) {
881882
Reference currentFrameInfo = PArguments.getCurrentFrameInfo(frame);
882883
currentFrameInfo.markAsEscaped();
883-
return readCallerNode.executeWith(currentFrameInfo, num);
884+
return readCallerNode.executeWith(currentFrameInfo, num, false);
884885
}
885886

886887
}
@@ -900,7 +901,7 @@ Object currentFrames(VirtualFrame frame,
900901
if (!getLanguage().singleThreadedAssumption.isValid()) {
901902
warnNode.warn(frame, RuntimeWarning, ErrorMessages.WARN_CURRENT_FRAMES_MULTITHREADED);
902903
}
903-
PFrame currentFrame = readCallerFrameNode.executeWith(frame, 0);
904+
PFrame currentFrame = readCallerFrameNode.executeWith(frame, 0, false);
904905
PDict result = PFactory.createDict(language);
905906
result.setDictStorage(setHashingStorageItem.execute(frame, inliningTarget, result.getDictStorage(), PThread.getThreadId(Thread.currentThread()), currentFrame));
906907
return result;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TypingModuleBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ static Object caller(VirtualFrame frame,
214214
@Cached(inline = false) PyObjectCallMethodObjArgs callMethod,
215215
@Cached(inline = false) ReadCallerFrameNode readCallerNode) {
216216
Reference currentFrameInfo = PArguments.getCurrentFrameInfo(frame);
217-
PFrame pFrame = readCallerNode.executeWith(currentFrameInfo, 0);
217+
PFrame pFrame = readCallerNode.executeWith(currentFrameInfo, 0, false);
218218
Object globals = getGlobalsNode.execute(frame, pFrame);
219219

220220
return callMethod.executeCached(frame, globals, T_GET, T___NAME__, PNone.NONE);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/WarningsModuleBuiltins.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
import com.oracle.graal.python.nodes.util.CannotCastException;
120120
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
121121
import com.oracle.graal.python.nodes.util.CastToTruffleStringNode;
122+
import com.oracle.graal.python.runtime.CallerFlags;
122123
import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext;
123124
import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData;
124125
import com.oracle.graal.python.runtime.PythonContext;
@@ -424,7 +425,7 @@ private PFrame getCallerFrame(VirtualFrame frame, int stackLevel, TruffleString[
424425
stackLevel--;
425426
selector = rootNode -> ReadCallerFrameNode.SkipInternalFramesSelector.INSTANCE.skip(rootNode) || isFilenameToSkip(skipFilePrefixes, rootNode);
426427
}
427-
return readCallerNode.executeWith(ref, selector, stackLevel);
428+
return readCallerNode.executeWith(ref, selector, stackLevel, false);
428429
}
429430

430431
@TruffleBoundary
@@ -986,7 +987,7 @@ private static TruffleString getSourceLine(Node node, PDict globals, int lineno)
986987
}
987988

988989
@Builtin(name = J_WARN, minNumOfPositionalArgs = 2, parameterNames = {"$mod", "message", "category", "stacklevel", "source",
989-
"skip_file_prefixes"}, declaresExplicitSelf = true, alwaysNeedsCallerFrame = true)
990+
"skip_file_prefixes"}, declaresExplicitSelf = true, callerFlags = CallerFlags.NEEDS_PFRAME)
990991
@ArgumentClinic(name = "category", defaultValue = "PNone.NONE")
991992
@ArgumentClinic(name = "stacklevel", conversion = ClinicConversion.Int, defaultValue = "1")
992993
@ArgumentClinic(name = "source", defaultValue = "PNone.NONE")

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextCEvalBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Object getFrame(
147147
@Cached GetCurrentFrameRef getCurrentFrameRef,
148148
@Cached ReadCallerFrameNode readCallerFrameNode) {
149149
PFrame.Reference reference = getCurrentFrameRef.execute(null, inliningTarget);
150-
return readCallerFrameNode.executeWith(reference, 0);
150+
return readCallerFrameNode.executeWith(reference, 0, false);
151151
}
152152
}
153153

@@ -215,7 +215,7 @@ Object get(
215215
@Cached GetCurrentFrameRef getCurrentFrameRef,
216216
@Cached ReadCallerFrameNode readCallerFrameNode) {
217217
PFrame.Reference frameRef = getCurrentFrameRef.execute(null, inliningTarget);
218-
PFrame pFrame = readCallerFrameNode.executeWith(frameRef, 0);
218+
PFrame pFrame = readCallerFrameNode.executeWith(frameRef, 0, false);
219219
return pFrame.getGlobals();
220220
}
221221
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextPyStateBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ PFrame get(@SuppressWarnings("unused") Object threadState,
221221
@Cached GetCurrentFrameRef getCurrentFrameRef,
222222
@Cached ReadCallerFrameNode readCallerFrameNode) {
223223
PFrame.Reference frameRef = getCurrentFrameRef.execute(null, inliningTarget);
224-
return readCallerFrameNode.executeWith(frameRef, 0);
224+
return readCallerFrameNode.executeWith(frameRef, 0, false);
225225
}
226226
}
227227

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ Object getBackref(VirtualFrame frame, PFrame self,
338338
// a) self is still on the stack and the caller isn't filled in
339339
// b) this frame has returned, but not (yet) to a Python caller
340340
// c) this frame has no caller (it is/was a top frame)
341-
callerFrame = readCallerFrame.executeWith(cur.getRef(), ReadCallerFrameNode.AllFramesSelector.INSTANCE, 0);
341+
callerFrame = readCallerFrame.executeWith(cur.getRef(), ReadCallerFrameNode.AllFramesSelector.INSTANCE, 0, false);
342342

343343
// We don't need to mark the caller frame as 'escaped' because if 'self' is
344344
// escaped, the caller frame will be escaped when leaving the current function.
@@ -368,7 +368,7 @@ private static PFrame materialize(VirtualFrame frame, Node inliningTarget, ReadC
368368
// Special case: the backref's PFrame object is not yet available; this is because
369369
// the frame is still on the stack. So we need to find and materialize it.
370370
for (int i = 0;; i++) {
371-
PFrame caller = readCallerFrameNode.executeWith(frame, i);
371+
PFrame caller = readCallerFrameNode.executeWith(frame, i, false);
372372
if (caller == null) {
373373
break;
374374
} else if (caller.getRef() == backref) {

0 commit comments

Comments
 (0)