60
60
import com .oracle .truffle .api .frame .Frame ;
61
61
import com .oracle .truffle .api .frame .MaterializedFrame ;
62
62
import com .oracle .truffle .api .frame .VirtualFrame ;
63
+ import com .oracle .truffle .api .nodes .BytecodeOSRNode ;
63
64
import com .oracle .truffle .api .nodes .ExplodeLoop ;
64
65
import com .oracle .truffle .api .profiles .ConditionProfile ;
65
66
import com .oracle .truffle .api .source .SourceSection ;
66
67
67
- public class PBytecodeGeneratorRootNode extends PRootNode {
68
+ public class PBytecodeGeneratorRootNode extends PRootNode implements BytecodeOSRNode {
68
69
private final PBytecodeRootNode rootNode ;
69
70
private final int resumeBci ;
70
71
private final int resumeStackTop ;
71
72
72
73
@ Child private ExecutionContext .CalleeContext calleeContext = ExecutionContext .CalleeContext .create ();
73
74
@ Child private IsBuiltinClassProfile errorProfile ;
74
75
@ Child private PRaiseNode raise = PRaiseNode .create ();
76
+ private final ConditionProfile returnProfile = ConditionProfile .create ();
77
+
78
+ @ CompilationFinal private Object osrMetadata ;
79
+ @ CompilationFinal (dimensions = 1 ) private FrameSlotType [] frameSlotTypes ;
75
80
76
81
private enum FrameSlotType {
77
82
Object ,
@@ -81,17 +86,13 @@ private enum FrameSlotType {
81
86
Boolean
82
87
}
83
88
84
- @ CompilationFinal (dimensions = 1 ) private FrameSlotType [] frameSlotTypes ;
85
-
86
- private final ConditionProfile returnProfile = ConditionProfile .create ();
87
-
88
89
@ TruffleBoundary
89
90
public PBytecodeGeneratorRootNode (PythonLanguage language , PBytecodeRootNode rootNode , int resumeBci , int resumeStackTop ) {
90
91
super (language , rootNode .getFrameDescriptor ());
91
92
this .rootNode = rootNode ;
92
93
this .resumeBci = resumeBci ;
93
94
this .resumeStackTop = resumeStackTop ;
94
- frameSlotTypes = new FrameSlotType [resumeStackTop ];
95
+ frameSlotTypes = new FrameSlotType [resumeStackTop + 1 ];
95
96
}
96
97
97
98
@ ExplodeLoop
@@ -153,7 +154,9 @@ private void copyFrameSlotsIntoVirtualFrame(MaterializedFrame generatorFrame, Vi
153
154
154
155
@ ExplodeLoop
155
156
private void copyFrameSlotsToGeneratorFrame (VirtualFrame virtualFrame , MaterializedFrame generatorFrame ) {
156
- for (int i = 0 ; i < frameSlotTypes .length ; i ++) {
157
+ int stackTop = getFrameDescriptor ().getNumberOfSlots ();
158
+ CompilerAsserts .partialEvaluationConstant (stackTop );
159
+ for (int i = 0 ; i < stackTop ; i ++) {
157
160
if (virtualFrame .isObject (i )) {
158
161
generatorFrame .setObject (i , virtualFrame .getObject (i ));
159
162
} else if (virtualFrame .isInt (i )) {
@@ -168,9 +171,6 @@ private void copyFrameSlotsToGeneratorFrame(VirtualFrame virtualFrame, Materiali
168
171
throw CompilerDirectives .shouldNotReachHere ("unexpected frame slot type" );
169
172
}
170
173
}
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
174
}
175
175
176
176
private void profileFrameSlots (MaterializedFrame generatorFrame ) {
@@ -192,6 +192,31 @@ private void profileFrameSlots(MaterializedFrame generatorFrame) {
192
192
}
193
193
}
194
194
195
+ @ Override
196
+ public Object executeOSR (VirtualFrame osrFrame , int target , Object interpreterState ) {
197
+ Integer osrStackTop = (Integer ) interpreterState ;
198
+ MaterializedFrame generatorFrame = PArguments .getGeneratorFrame (osrFrame );
199
+ copyFrameSlotsIntoVirtualFrame (generatorFrame , osrFrame );
200
+ copyOSRStackRemainderIntoVirtualFrame (generatorFrame , osrFrame , osrStackTop );
201
+ try {
202
+ return rootNode .executeFromBci (osrFrame , osrFrame , this , target , osrStackTop );
203
+ } finally {
204
+ copyFrameSlotsToGeneratorFrame (osrFrame , generatorFrame );
205
+ }
206
+ }
207
+
208
+ @ ExplodeLoop
209
+ private void copyOSRStackRemainderIntoVirtualFrame (MaterializedFrame generatorFrame , VirtualFrame osrFrame , int stackTop ) {
210
+ /*
211
+ * In addition to local variables and stack slots present at resume, OSR needs to also
212
+ * revirtualize stack items that have been pushed since resume. Stack slots at a back edge
213
+ * should never be primitives.
214
+ */
215
+ for (int i = resumeStackTop ; i <= stackTop ; i ++) {
216
+ osrFrame .setObject (i , generatorFrame .getObject (i ));
217
+ }
218
+ }
219
+
195
220
@ Override
196
221
public Object execute (VirtualFrame frame ) {
197
222
calleeContext .enter (frame );
@@ -206,22 +231,23 @@ public Object execute(VirtualFrame frame) {
206
231
PArguments .setException (frame , localException == null ? outerException : localException );
207
232
Object result ;
208
233
Frame localFrame ;
209
- if (CompilerDirectives .inInterpreter ()) {
234
+ boolean usingMaterializedFrame = CompilerDirectives .inInterpreter ();
235
+ if (usingMaterializedFrame ) {
210
236
profileFrameSlots (generatorFrame );
211
237
localFrame = generatorFrame ;
212
238
} else {
213
239
copyFrameSlotsIntoVirtualFrame (generatorFrame , frame );
214
240
localFrame = frame ;
215
241
}
216
242
try {
217
- result = rootNode .executeFromBci (frame , localFrame , resumeBci , resumeStackTop );
243
+ result = rootNode .executeFromBci (frame , localFrame , this , resumeBci , resumeStackTop );
218
244
} catch (PException pe ) {
219
245
// PEP 479 - StopIteration raised from generator body needs to be wrapped in
220
246
// RuntimeError
221
247
pe .expectStopIteration (getErrorProfile ());
222
248
throw raise .raise (RuntimeError , pe .setCatchingFrameAndGetEscapedException (frame , this ), ErrorMessages .GENERATOR_RAISED_STOPITER );
223
249
} finally {
224
- if (CompilerDirectives . inCompiledCode () ) {
250
+ if (! usingMaterializedFrame ) {
225
251
copyFrameSlotsToGeneratorFrame (frame , generatorFrame );
226
252
}
227
253
calleeContext .exit (frame , this );
@@ -243,6 +269,26 @@ public Object execute(VirtualFrame frame) {
243
269
return result ;
244
270
}
245
271
272
+ @ Override
273
+ public Object getOSRMetadata () {
274
+ return osrMetadata ;
275
+ }
276
+
277
+ @ Override
278
+ public void setOSRMetadata (Object osrMetadata ) {
279
+ this .osrMetadata = osrMetadata ;
280
+ }
281
+
282
+ @ Override
283
+ public Object [] storeParentFrameInArguments (VirtualFrame parentFrame ) {
284
+ return rootNode .storeParentFrameInArguments (parentFrame );
285
+ }
286
+
287
+ @ Override
288
+ public Frame restoreParentFrameFromArguments (Object [] arguments ) {
289
+ return rootNode .restoreParentFrameFromArguments (arguments );
290
+ }
291
+
246
292
@ Override
247
293
public String getName () {
248
294
return rootNode .getName ();
@@ -251,7 +297,7 @@ public String getName() {
251
297
@ Override
252
298
public String toString () {
253
299
CompilerAsserts .neverPartOfCompilation ();
254
- return "<bytecode " + rootNode .getName () + ">" ;
300
+ return "<bytecode " + rootNode .getName () + " (generator resume bci=" + resumeBci + ") >" ;
255
301
}
256
302
257
303
@ Override
0 commit comments