4747import com .oracle .graal .python .nodes .PRootNode ;
4848import com .oracle .graal .python .nodes .bytecode .BytecodeFrameInfo ;
4949import com .oracle .graal .python .nodes .bytecode .FrameInfo ;
50- import com .oracle .graal .python .nodes .bytecode_dsl .BytecodeDSLFrameInfo ;
5150import com .oracle .graal .python .nodes .bytecode_dsl .PBytecodeDSLRootNode ;
5251import com .oracle .graal .python .runtime .PythonOptions ;
5352import com .oracle .graal .python .runtime .object .PFactory ;
5453import com .oracle .graal .python .util .PythonUtils ;
54+ import com .oracle .truffle .api .CompilerAsserts ;
5555import com .oracle .truffle .api .Truffle ;
5656import com .oracle .truffle .api .bytecode .BytecodeNode ;
5757import com .oracle .truffle .api .dsl .Bind ;
6767import com .oracle .truffle .api .frame .Frame ;
6868import com .oracle .truffle .api .frame .FrameDescriptor ;
6969import com .oracle .truffle .api .frame .MaterializedFrame ;
70- import com .oracle .truffle .api .nodes .ExplodeLoop ;
7170import com .oracle .truffle .api .nodes .Node ;
72- import com .oracle .truffle .api .nodes .RootNode ;
7371import com .oracle .truffle .api .profiles .InlinedConditionProfile ;
72+ import com .oracle .truffle .api .profiles .InlinedIntValueProfile ;
73+ import com .oracle .truffle .api .profiles .ValueProfile ;
7474
7575/**
7676 * This node makes sure that the current frame has a filled-in PFrame object with a backref
@@ -125,14 +125,17 @@ public final PFrame executeOnStack(Frame frameToMaterialize, PRootNode location,
125125 * root nodes, we fetch the root node from the frame descriptor.
126126 */
127127 public final PFrame executeOnStack (boolean markAsEscaped , boolean forceSync , Frame frameToMaterialize ) {
128- Node location ;
129- RootNode rootNode = PArguments .getCurrentFrameInfo (frameToMaterialize ).getRootNode ();
130- if (PythonOptions .ENABLE_BYTECODE_DSL_INTERPRETER && PGenerator .unwrapContinuationRoot (rootNode ) instanceof PBytecodeDSLRootNode ) {
131- assert this .isAdoptable ();
132- location = BytecodeNode .get (this );
133- assert location != null ;
128+ Node location = this ;
129+ if (!PythonOptions .ENABLE_BYTECODE_DSL_INTERPRETER ) {
130+ if (!location .isAdoptable ()) {
131+ // This should only happen in uncached manual bytecode interpreter, we are fine with
132+ // root node in such case
133+ location = PArguments .getCurrentFrameInfo (frameToMaterialize ).getRootNode ();
134+ }
134135 } else {
135- location = rootNode ;
136+ // We will need EncapsulatingNodeReference or thread the BytecodeNode as argument for
137+ // BytecodeDSL uncached execution
138+ assert this .isAdoptable ();
136139 }
137140 return execute (location , markAsEscaped , forceSync , frameToMaterialize );
138141 }
@@ -155,29 +158,17 @@ public final PFrame execute(Node location, boolean markAsEscaped, boolean forceS
155158
156159 abstract PFrame executeImpl (Node location , boolean markAsEscaped , boolean forceSync , Frame frameToMaterialize );
157160
158- @ Specialization (guards = {
159- "cachedFD == frameToMaterialize.getFrameDescriptor()" , //
160- "getPFrame(frameToMaterialize) == null" , //
161- "!isGeneratorFrame(frameToMaterialize)" , //
162- "!hasCustomLocals(frameToMaterialize)" }, limit = "1" )
161+ @ Specialization (guards = {"getPFrame(frameToMaterialize) == null" , "!isGeneratorFrame(frameToMaterialize)" , "!hasCustomLocals(frameToMaterialize)" })
163162 static PFrame freshPFrameCachedFD (Node location , boolean markAsEscaped , boolean forceSync , Frame frameToMaterialize ,
164- @ Cached (value = "frameToMaterialize.getFrameDescriptor()" ) FrameDescriptor cachedFD ,
165163 @ Bind PythonLanguage language ,
164+ @ Cached (inline = false ) ValueProfile cachedFDProfile ,
166165 @ Shared ("syncValuesNode" ) @ Cached SyncFrameValuesNode syncValuesNode ) {
166+ FrameDescriptor cachedFD = cachedFDProfile .profile (frameToMaterialize .getFrameDescriptor ());
167167 MaterializedFrame locals = createLocalsFrame (cachedFD );
168168 PFrame escapedFrame = PFactory .createPFrame (language , PArguments .getCurrentFrameInfo (frameToMaterialize ), location , locals );
169169 return doEscapeFrame (frameToMaterialize , escapedFrame , markAsEscaped , forceSync , location , syncValuesNode );
170170 }
171171
172- @ Specialization (guards = {"getPFrame(frameToMaterialize) == null" , "!isGeneratorFrame(frameToMaterialize)" , "!hasCustomLocals(frameToMaterialize)" }, replaces = "freshPFrameCachedFD" )
173- static PFrame freshPFrame (Node location , boolean markAsEscaped , boolean forceSync , Frame frameToMaterialize ,
174- @ Bind PythonLanguage language ,
175- @ Shared ("syncValuesNode" ) @ Cached SyncFrameValuesNode syncValuesNode ) {
176- MaterializedFrame locals = createLocalsFrame (frameToMaterialize .getFrameDescriptor ());
177- PFrame escapedFrame = PFactory .createPFrame (language , PArguments .getCurrentFrameInfo (frameToMaterialize ), location , locals );
178- return doEscapeFrame (frameToMaterialize , escapedFrame , markAsEscaped , forceSync , location , syncValuesNode );
179- }
180-
181172 @ Specialization (guards = {"getPFrame(frameToMaterialize) == null" , "!isGeneratorFrame(frameToMaterialize)" , "hasCustomLocals(frameToMaterialize)" })
182173 static PFrame freshPFrameCusstomLocals (Node location , boolean markAsEscaped , @ SuppressWarnings ("unused" ) boolean forceSync ,
183174 Frame frameToMaterialize ,
@@ -203,7 +194,7 @@ static PFrame alreadyEscapedFrame(@SuppressWarnings("unused") Node location, boo
203194 @ Cached InlinedConditionProfile syncProfile ) {
204195 PFrame pyFrame = getPFrame (frameToMaterialize );
205196 if (syncProfile .profile (inliningTarget , forceSync && !PGenerator .isGeneratorFrame (frameToMaterialize ))) {
206- syncValuesNode .execute (pyFrame , frameToMaterialize );
197+ syncValuesNode .execute (pyFrame , frameToMaterialize , location );
207198 }
208199 if (markAsEscaped ) {
209200 pyFrame .getRef ().markAsEscaped ();
@@ -231,6 +222,7 @@ private static void processBytecodeFrame(Frame frameToMaterialize, PFrame pyFram
231222 if (PythonOptions .ENABLE_BYTECODE_DSL_INTERPRETER ) {
232223 BytecodeNode bytecodeNode ;
233224 assert !(location instanceof PBytecodeDSLRootNode ); // we need BytecodeNode or its child
225+ CompilerAsserts .partialEvaluationConstant (location );
234226 bytecodeNode = BytecodeNode .get (location );
235227 if (bytecodeNode != null ) {
236228 pyFrame .setBci (bytecodeNode .getBytecodeIndex (frameToMaterialize ));
@@ -255,7 +247,7 @@ private static PFrame doEscapeFrame(Frame frameToMaterialize, PFrame escapedFram
255247 // on a freshly created PFrame, we do always sync the arguments
256248 PArguments .synchronizeArgs (frameToMaterialize , escapedFrame );
257249 if (forceSync ) {
258- syncValuesNode .execute (escapedFrame , frameToMaterialize );
250+ syncValuesNode .execute (escapedFrame , frameToMaterialize , location );
259251 }
260252 if (markAsEscaped ) {
261253 topFrameRef .markAsEscaped ();
@@ -282,37 +274,32 @@ protected static PFrame getPFrame(Frame frame) {
282274 @ GenerateUncached
283275 public abstract static class SyncFrameValuesNode extends Node {
284276
285- public abstract void execute (PFrame pyFrame , Frame frameToSync );
277+ public abstract void execute (PFrame pyFrame , Frame frameToSync , Node location );
286278
287- @ Specialization (guards = {"!pyFrame.hasCustomLocals()" ,
288- "frameToSync.getFrameDescriptor() == cachedFd" }, limit = "1" )
289- @ ExplodeLoop
290- static void doSyncCached (PFrame pyFrame , Frame frameToSync ,
291- @ Cached (value = "frameToSync.getFrameDescriptor()" ) FrameDescriptor cachedFd ) {
279+ @ Specialization (guards = "!pyFrame.hasCustomLocals()" )
280+ static void doSync (PFrame pyFrame , Frame frameToSync , Node location ,
281+ @ Bind Node inliningTarget ,
282+ @ Cached (inline = false ) ValueProfile frameDescriptorProfile ,
283+ @ Cached InlinedIntValueProfile slotCountProfile ) {
284+ FrameDescriptor cachedFd = frameDescriptorProfile .profile (frameToSync .getFrameDescriptor ());
292285 MaterializedFrame target = pyFrame .getLocals ();
293286 assert cachedFd == target .getFrameDescriptor ();
294- int slotCount = variableSlotCount (cachedFd );
287+ int slotCount = slotCountProfile . profile ( inliningTarget , variableSlotCount (cachedFd ) );
295288
296289 if (PythonOptions .ENABLE_BYTECODE_DSL_INTERPRETER ) {
297- FrameInfo info = ( FrameInfo ) cachedFd . getInfo ( );
298- if ( info instanceof BytecodeDSLFrameInfo bytecodeDSLFrameInfo ) {
299- PBytecodeDSLRootNode rootNode = bytecodeDSLFrameInfo . getRootNode ();
300- rootNode . getBytecodeNode () .copyLocalValues (0 , frameToSync , target , 0 , slotCount );
290+ CompilerAsserts . partialEvaluationConstant ( location );
291+ BytecodeNode bytecodeNode = BytecodeNode . get ( location );
292+ if ( bytecodeNode != null ) {
293+ bytecodeNode .copyLocalValues (0 , frameToSync , target , 0 , slotCount );
301294 }
302295 } else {
303296 frameToSync .copyTo (0 , target , 0 , slotCount );
304297 }
305298 }
306299
307- @ Specialization (guards = "!pyFrame.hasCustomLocals()" , replaces = "doSyncCached" )
308- @ ExplodeLoop
309- static void doSync (PFrame pyFrame , Frame frameToSync ) {
310- doSyncCached (pyFrame , frameToSync , frameToSync .getFrameDescriptor ());
311- }
312-
313300 @ Specialization (guards = "pyFrame.hasCustomLocals()" )
314301 @ SuppressWarnings ("unused" )
315- static void doCustomLocals (PFrame pyFrame , Frame frameToSync ) {
302+ static void doCustomLocals (PFrame pyFrame , Frame frameToSync , Node location ) {
316303 // nothing to do
317304 }
318305
0 commit comments