@@ -712,7 +712,7 @@ public Object execute(VirtualFrame virtualFrame) {
712712 copyArgsAndCells (virtualFrame , virtualFrame .getArguments ());
713713 }
714714
715- return executeFromBci (virtualFrame , virtualFrame , virtualFrame , this , 0 , getInitialStackTop ());
715+ return executeFromBci (virtualFrame , virtualFrame , virtualFrame , this , 0 , getInitialStackTop (), Integer . MAX_VALUE );
716716 } finally {
717717 calleeContext .exit (virtualFrame , this );
718718 }
@@ -731,14 +731,25 @@ public Frame restoreParentFrameFromArguments(Object[] arguments) {
731731 }
732732
733733 @ Override
734- public Object executeOSR (VirtualFrame osrFrame , int target , Object interpreterState ) {
735- return executeFromBci (osrFrame , osrFrame , osrFrame , this , target , (Integer ) interpreterState );
734+ public Object executeOSR (VirtualFrame osrFrame , int target , Object interpreterStateObject ) {
735+ OSRInterpreterState interpreterState = (OSRInterpreterState ) interpreterStateObject ;
736+ return executeFromBci (osrFrame , osrFrame , osrFrame , this , target , interpreterState .stackTop , interpreterState .loopEndBci );
737+ }
738+
739+ private static final class OSRContinuation {
740+ public final int bci ;
741+ public final int stackTop ;
742+
743+ private OSRContinuation (int bci , int stackTop ) {
744+ this .bci = bci ;
745+ this .stackTop = stackTop ;
746+ }
736747 }
737748
738749 @ BytecodeInterpreterSwitch
739750 @ ExplodeLoop (kind = ExplodeLoop .LoopExplosionKind .MERGE_EXPLODE )
740751 @ SuppressWarnings ("fallthrough" )
741- Object executeFromBci (VirtualFrame virtualFrame , Frame localFrame , Frame stackFrame , BytecodeOSRNode osrNode , int initialBci , int initialStackTop ) {
752+ Object executeFromBci (VirtualFrame virtualFrame , Frame localFrame , Frame stackFrame , BytecodeOSRNode osrNode , int initialBci , int initialStackTop , int loopEndBci ) {
742753 Object globals = PArguments .getGlobals (virtualFrame );
743754 Object locals = PArguments .getSpecialArgument (virtualFrame );
744755
@@ -787,6 +798,22 @@ Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, Frame stackFr
787798 CompilerAsserts .partialEvaluationConstant (bci );
788799 CompilerAsserts .partialEvaluationConstant (stackTop );
789800
801+ if (CompilerDirectives .inCompiledCode () && bci > loopEndBci ) {
802+ /*
803+ * This means we're in OSR and we just jumped out of the OSR compiled loop. We want
804+ * to return to the caller to continue in interpreter again otherwise we would most
805+ * likely deopt on the next instruction. The caller handles the special return value
806+ * in JUMP_BACKWARD. In generators, we need to additionally copy the stack items
807+ * back to the generator frame.
808+ */
809+ if (localFrame != stackFrame ) {
810+ copyStackSlotsToGeneratorFrame (stackFrame , localFrame , stackTop );
811+ // Clear slots that were popped (if any)
812+ clearFrameSlots (localFrame , stackTop + 1 , initialStackTop );
813+ }
814+ return new OSRContinuation (bci , stackTop );
815+ }
816+
790817 try {
791818 switch (bc ) {
792819 case OpCodesConstants .LOAD_NONE :
@@ -1185,12 +1212,22 @@ Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, Frame stackFr
11851212 * will get mixed up. To retain such state, put it into the frame
11861213 * instead.
11871214 */
1188- Object osrResult = BytecodeOSRNode .tryOSR (osrNode , bci , stackTop , null , virtualFrame );
1215+ Object osrResult = BytecodeOSRNode .tryOSR (osrNode , bci , new OSRInterpreterState ( stackTop , beginBci ) , null , virtualFrame );
11891216 if (osrResult != null ) {
1190- if (CompilerDirectives .hasNextTier () && loopCount [0 ] > 0 ) {
1191- LoopNode .reportLoopCount (this , loopCount [0 ]);
1217+ if (osrResult instanceof OSRContinuation ) {
1218+ // We should continue executing in interpreter after the loop
1219+ OSRContinuation continuation = (OSRContinuation ) osrResult ;
1220+ bci = continuation .bci ;
1221+ stackTop = continuation .stackTop ;
1222+ oparg = 0 ;
1223+ continue ;
1224+ } else {
1225+ // We reached a return/yield
1226+ if (CompilerDirectives .hasNextTier () && loopCount [0 ] > 0 ) {
1227+ LoopNode .reportLoopCount (this , loopCount [0 ]);
1228+ }
1229+ return osrResult ;
11921230 }
1193- return osrResult ;
11941231 }
11951232 }
11961233 oparg = 0 ;
0 commit comments