Skip to content

Commit 9ada324

Browse files
committed
Revirtualize generator frame
1 parent e8d0b40 commit 9ada324

File tree

2 files changed

+127
-9
lines changed

2 files changed

+127
-9
lines changed

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

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,12 @@
5555
import com.oracle.graal.python.runtime.exception.PException;
5656
import com.oracle.truffle.api.CompilerAsserts;
5757
import com.oracle.truffle.api.CompilerDirectives;
58+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
5859
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
60+
import com.oracle.truffle.api.frame.Frame;
5961
import com.oracle.truffle.api.frame.MaterializedFrame;
6062
import com.oracle.truffle.api.frame.VirtualFrame;
63+
import com.oracle.truffle.api.nodes.ExplodeLoop;
6164
import com.oracle.truffle.api.profiles.ConditionProfile;
6265
import com.oracle.truffle.api.source.SourceSection;
6366

@@ -70,6 +73,16 @@ public class PBytecodeGeneratorRootNode extends PRootNode {
7073
@Child private IsBuiltinClassProfile errorProfile;
7174
@Child private PRaiseNode raise = PRaiseNode.create();
7275

76+
private enum FrameSlotType {
77+
Object,
78+
Int,
79+
Long,
80+
Double,
81+
Boolean
82+
}
83+
84+
@CompilationFinal(dimensions = 1) private FrameSlotType[] frameSlotTypes;
85+
7386
private final ConditionProfile returnProfile = ConditionProfile.create();
7487

7588
@TruffleBoundary
@@ -78,6 +91,105 @@ public PBytecodeGeneratorRootNode(PythonLanguage language, PBytecodeRootNode roo
7891
this.rootNode = rootNode;
7992
this.resumeBci = resumeBci;
8093
this.resumeStackTop = resumeStackTop;
94+
frameSlotTypes = new FrameSlotType[resumeStackTop];
95+
}
96+
97+
@ExplodeLoop
98+
private void copyFrameSlotsIntoVirtualFrame(MaterializedFrame generatorFrame, VirtualFrame virtualFrame) {
99+
for (int i = 0; i < frameSlotTypes.length; i++) {
100+
switch (frameSlotTypes[i]) {
101+
case Object:
102+
if (generatorFrame.isObject(i)) {
103+
virtualFrame.setObject(i, generatorFrame.getObject(i));
104+
continue;
105+
}
106+
break;
107+
case Int:
108+
if (generatorFrame.isInt(i)) {
109+
virtualFrame.setInt(i, generatorFrame.getInt(i));
110+
continue;
111+
}
112+
break;
113+
case Long:
114+
if (generatorFrame.isLong(i)) {
115+
virtualFrame.setLong(i, generatorFrame.getLong(i));
116+
continue;
117+
}
118+
break;
119+
case Double:
120+
if (generatorFrame.isDouble(i)) {
121+
virtualFrame.setDouble(i, generatorFrame.getDouble(i));
122+
continue;
123+
}
124+
break;
125+
case Boolean:
126+
if (generatorFrame.isBoolean(i)) {
127+
virtualFrame.setBoolean(i, generatorFrame.getBoolean(i));
128+
continue;
129+
}
130+
break;
131+
}
132+
CompilerDirectives.transferToInterpreterAndInvalidate();
133+
if (generatorFrame.isObject(i)) {
134+
virtualFrame.setObject(i, generatorFrame.getObject(i));
135+
frameSlotTypes[i] = FrameSlotType.Object;
136+
} else if (generatorFrame.isInt(i)) {
137+
virtualFrame.setInt(i, generatorFrame.getInt(i));
138+
frameSlotTypes[i] = FrameSlotType.Int;
139+
} else if (generatorFrame.isLong(i)) {
140+
virtualFrame.setLong(i, generatorFrame.getLong(i));
141+
frameSlotTypes[i] = FrameSlotType.Long;
142+
} else if (generatorFrame.isDouble(i)) {
143+
virtualFrame.setDouble(i, generatorFrame.getDouble(i));
144+
frameSlotTypes[i] = FrameSlotType.Double;
145+
} else if (generatorFrame.isBoolean(i)) {
146+
virtualFrame.setBoolean(i, generatorFrame.getBoolean(i));
147+
frameSlotTypes[i] = FrameSlotType.Boolean;
148+
} else {
149+
throw new IllegalStateException("unexpected frame slot type");
150+
}
151+
}
152+
}
153+
154+
@ExplodeLoop
155+
private void copyFrameSlotsToGeneratorFrame(VirtualFrame virtualFrame, MaterializedFrame generatorFrame) {
156+
for (int i = 0; i < frameSlotTypes.length; i++) {
157+
if (virtualFrame.isObject(i)) {
158+
generatorFrame.setObject(i, virtualFrame.getObject(i));
159+
} else if (virtualFrame.isInt(i)) {
160+
generatorFrame.setInt(i, virtualFrame.getInt(i));
161+
} else if (virtualFrame.isLong(i)) {
162+
generatorFrame.setLong(i, virtualFrame.getLong(i));
163+
} else if (virtualFrame.isDouble(i)) {
164+
generatorFrame.setDouble(i, virtualFrame.getDouble(i));
165+
} else if (virtualFrame.isBoolean(i)) {
166+
generatorFrame.setBoolean(i, virtualFrame.getBoolean(i));
167+
} else {
168+
throw CompilerDirectives.shouldNotReachHere("unexpected frame slot type");
169+
}
170+
}
171+
generatorFrame.setInt(rootNode.bcioffset, virtualFrame.getInt(rootNode.bcioffset));
172+
generatorFrame.setInt(rootNode.generatorStackTopOffset, virtualFrame.getInt(rootNode.generatorStackTopOffset));
173+
generatorFrame.setObject(rootNode.generatorReturnOffset, virtualFrame.getObject(rootNode.generatorReturnOffset));
174+
}
175+
176+
private void profileFrameSlots(MaterializedFrame generatorFrame) {
177+
CompilerAsserts.neverPartOfCompilation();
178+
for (int i = 0; i < frameSlotTypes.length; i++) {
179+
if (generatorFrame.isObject(i)) {
180+
frameSlotTypes[i] = FrameSlotType.Object;
181+
} else if (generatorFrame.isInt(i)) {
182+
frameSlotTypes[i] = FrameSlotType.Int;
183+
} else if (generatorFrame.isLong(i)) {
184+
frameSlotTypes[i] = FrameSlotType.Long;
185+
} else if (generatorFrame.isDouble(i)) {
186+
frameSlotTypes[i] = FrameSlotType.Double;
187+
} else if (generatorFrame.isBoolean(i)) {
188+
frameSlotTypes[i] = FrameSlotType.Boolean;
189+
} else {
190+
throw new IllegalStateException("unexpected frame slot type");
191+
}
192+
}
81193
}
82194

83195
@Override
@@ -93,14 +205,25 @@ public Object execute(VirtualFrame frame) {
93205
PException outerException = PArguments.getException(frame);
94206
PArguments.setException(frame, localException == null ? outerException : localException);
95207
Object result;
208+
Frame localFrame;
209+
if (CompilerDirectives.inInterpreter()) {
210+
profileFrameSlots(generatorFrame);
211+
localFrame = generatorFrame;
212+
} else {
213+
copyFrameSlotsIntoVirtualFrame(generatorFrame, frame);
214+
localFrame = frame;
215+
}
96216
try {
97-
result = rootNode.executeFromBci(frame, resumeBci, resumeStackTop);
217+
result = rootNode.executeFromBci(frame, localFrame, resumeBci, resumeStackTop);
98218
} catch (PException pe) {
99219
// PEP 479 - StopIteration raised from generator body needs to be wrapped in
100220
// RuntimeError
101221
pe.expectStopIteration(getErrorProfile());
102222
throw raise.raise(RuntimeError, pe.setCatchingFrameAndGetEscapedException(frame, this), ErrorMessages.GENERATOR_RAISED_STOPITER);
103223
} finally {
224+
if (CompilerDirectives.inCompiledCode()) {
225+
copyFrameSlotsToGeneratorFrame(frame, generatorFrame);
226+
}
104227
calleeContext.exit(frame, this);
105228
PException exception = PArguments.getException(frame);
106229
if (exception != outerException && exception != PException.NO_EXCEPTION) {

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ public Object execute(VirtualFrame virtualFrame) {
720720
copyArgsAndCells(virtualFrame, virtualFrame.getArguments());
721721
}
722722

723-
return executeFromBci(virtualFrame, 0, getInitialStackTop());
723+
return executeFromBci(virtualFrame, virtualFrame, 0, getInitialStackTop());
724724
} finally {
725725
calleeContext.exit(virtualFrame, this);
726726
}
@@ -740,26 +740,21 @@ public Frame restoreParentFrameFromArguments(Object[] arguments) {
740740

741741
@Override
742742
public Object executeOSR(VirtualFrame osrFrame, int target, Object interpreterState) {
743-
return executeFromBci(osrFrame, target, (Integer) interpreterState);
743+
return executeFromBci(osrFrame, osrFrame, target, (Integer) interpreterState);
744744
}
745745

746746
@BytecodeInterpreterSwitch
747747
@ExplodeLoop(kind = ExplodeLoop.LoopExplosionKind.MERGE_EXPLODE)
748748
@SuppressWarnings("fallthrough")
749-
Object executeFromBci(VirtualFrame virtualFrame, int initialBci, int initialStackTop) {
749+
Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, int initialBci, int initialStackTop) {
750750
Object globals = PArguments.getGlobals(virtualFrame);
751751
Object locals = PArguments.getSpecialArgument(virtualFrame);
752752

753753
int loopCount = 0;
754754
int stackTop = initialStackTop;
755755
int bci = initialBci;
756756

757-
Frame localFrame = virtualFrame;
758757
boolean isGeneratorOrCoroutine = co.isGeneratorOrCoroutine();
759-
if (isGeneratorOrCoroutine) {
760-
localFrame = PArguments.getGeneratorFrame(virtualFrame);
761-
}
762-
763758
byte[] localBC = bytecode;
764759
int[] localArgs = extraArgs;
765760
Object[] localConsts = consts;

0 commit comments

Comments
 (0)