Skip to content

Commit deea716

Browse files
committed
Avoid syncing locals back to frame if not accessed
1 parent 07fd5e2 commit deea716

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,9 @@ Object getUpdating(VirtualFrame frame, PFrame self,
306306
PFrame pyFrame = materializeNode.executeOnStack(false, true, frame);
307307
assert pyFrame == self;
308308
}
309-
return getFrameLocalsNode.execute(inliningTarget, self);
309+
Object locals = getFrameLocalsNode.execute(inliningTarget, self);
310+
self.setLocalsAccessed(true);
311+
return locals;
310312
}
311313
}
312314

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public final class PFrame extends PythonBuiltinObject {
8686
public static final int NO_JUMP = -2;
8787
private int jumpDestLine = DISALLOW_JUMPS;
8888
private Object localTraceFun = null;
89+
private boolean localsAccessed;
8990

9091
private boolean traceLine = true;
9192

@@ -119,6 +120,14 @@ public void setJumpDestLine(int jumpDestLine) {
119120
this.jumpDestLine = jumpDestLine;
120121
}
121122

123+
public boolean localsAccessed() {
124+
return localsAccessed;
125+
}
126+
127+
public void setLocalsAccessed(boolean localsAccessed) {
128+
this.localsAccessed = localsAccessed;
129+
}
130+
122131
// TODO: frames: this is a large object, think about how to make this
123132
// smaller
124133
public static final class Reference {

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod
615615
private static final byte TRACE_PROFILE_LINE = 1;
616616
private static final byte TRACE_PROFILE_NEW_FRAME = 1 << 1;
617617
private static final byte TRACE_PROFILE_EXISTING_FRAME = 1 << 2;
618+
private static final byte TRACE_PROFILE_SYNC_LOCALS_BACK = 1 << 3;
618619
@CompilationFinal(dimensions = 1) byte[] traceProfileData;
619620

620621
@CompilationFinal private Object osrMetadata;
@@ -3254,7 +3255,7 @@ private void invokeTraceFunction(VirtualFrame virtualFrame, Object arg, PythonCo
32543255
pyFrame.setLineLock(line);
32553256
}
32563257
Object result = doInvokeTraceFunction(event, pyFrame, traceFn, nonNullArg);
3257-
syncLocalsBackToFrame(virtualFrame, pyFrame);
3258+
syncLocalsBackToFrame(virtualFrame, pyFrame, bci);
32583259
// https://github.com/python/cpython/issues/104232
32593260
if (useLocalFn) {
32603261
Object realResult = result == PNone.NONE ? traceFn : result;
@@ -3279,15 +3280,19 @@ private void invokeTraceFunction(VirtualFrame virtualFrame, Object arg, PythonCo
32793280
private static Object doInvokeTraceFunction(PythonContext.TraceEvent event, PFrame pyFrame, Object traceFn, Object nonNullArg) {
32803281
// Force locals dict sync, so that we can sync them back later
32813282
GetFrameLocalsNode.executeUncached(pyFrame);
3283+
pyFrame.setLocalsAccessed(false);
32823284
return CallTernaryMethodNode.getUncached().execute(null, traceFn, pyFrame, event.pythonName, nonNullArg);
32833285
}
32843286

3285-
private void syncLocalsBackToFrame(VirtualFrame virtualFrame, PFrame pyFrame) {
3287+
private void syncLocalsBackToFrame(VirtualFrame virtualFrame, PFrame pyFrame, int bci) {
32863288
Frame localFrame = virtualFrame;
32873289
if (co.isGeneratorOrCoroutine()) {
32883290
localFrame = PArguments.getGeneratorFrame(virtualFrame);
32893291
}
3290-
GetFrameLocalsNode.syncLocalsBackToFrame(co, this, pyFrame, localFrame);
3292+
if (pyFrame.localsAccessed()) {
3293+
enterTraceProfile(bci, TRACE_PROFILE_SYNC_LOCALS_BACK);
3294+
GetFrameLocalsNode.syncLocalsBackToFrame(co, this, pyFrame, localFrame);
3295+
}
32913296
}
32923297

32933298
private void profileCEvent(VirtualFrame virtualFrame, Object callable, PythonContext.ProfileEvent event, MutableLoopData mutableData, byte tracingOrProfilingEnabled, int bci) {
@@ -3327,7 +3332,7 @@ private void invokeProfileFunction(VirtualFrame virtualFrame, Object arg, Python
33273332

33283333
try {
33293334
Object result = doInvokeProfileFunction(arg, event, pyFrame, profileFun);
3330-
syncLocalsBackToFrame(virtualFrame, pyFrame);
3335+
syncLocalsBackToFrame(virtualFrame, pyFrame, bci);
33313336
Object realResult = result == PNone.NONE ? null : result;
33323337
pyFrame.setLocalTraceFun(realResult);
33333338
} catch (Throwable e) {
@@ -3342,6 +3347,7 @@ private void invokeProfileFunction(VirtualFrame virtualFrame, Object arg, Python
33423347
private static Object doInvokeProfileFunction(Object arg, PythonContext.ProfileEvent event, PFrame pyFrame, Object profileFun) {
33433348
// Force locals dict sync, so that we can sync them back later
33443349
GetFrameLocalsNode.executeUncached(pyFrame);
3350+
pyFrame.setLocalsAccessed(false);
33453351
return CallTernaryMethodNode.getUncached().execute(null, profileFun, pyFrame, event.name, arg == null ? PNone.NONE : arg);
33463352
}
33473353

0 commit comments

Comments
 (0)