@@ -712,7 +712,7 @@ public Object execute(VirtualFrame virtualFrame) {
712
712
copyArgsAndCells (virtualFrame , virtualFrame .getArguments ());
713
713
}
714
714
715
- return executeFromBci (virtualFrame , virtualFrame , virtualFrame , this , 0 , getInitialStackTop ());
715
+ return executeFromBci (virtualFrame , virtualFrame , virtualFrame , this , 0 , getInitialStackTop (), Integer . MAX_VALUE );
716
716
} finally {
717
717
calleeContext .exit (virtualFrame , this );
718
718
}
@@ -731,14 +731,25 @@ public Frame restoreParentFrameFromArguments(Object[] arguments) {
731
731
}
732
732
733
733
@ 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
+ }
736
747
}
737
748
738
749
@ BytecodeInterpreterSwitch
739
750
@ ExplodeLoop (kind = ExplodeLoop .LoopExplosionKind .MERGE_EXPLODE )
740
751
@ 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 ) {
742
753
Object globals = PArguments .getGlobals (virtualFrame );
743
754
Object locals = PArguments .getSpecialArgument (virtualFrame );
744
755
@@ -787,6 +798,22 @@ Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, Frame stackFr
787
798
CompilerAsserts .partialEvaluationConstant (bci );
788
799
CompilerAsserts .partialEvaluationConstant (stackTop );
789
800
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
+
790
817
try {
791
818
switch (bc ) {
792
819
case OpCodesConstants .LOAD_NONE :
@@ -1185,12 +1212,22 @@ Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, Frame stackFr
1185
1212
* will get mixed up. To retain such state, put it into the frame
1186
1213
* instead.
1187
1214
*/
1188
- Object osrResult = BytecodeOSRNode .tryOSR (osrNode , bci , stackTop , null , virtualFrame );
1215
+ Object osrResult = BytecodeOSRNode .tryOSR (osrNode , bci , new OSRInterpreterState ( stackTop , beginBci ) , null , virtualFrame );
1189
1216
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 ;
1192
1230
}
1193
- return osrResult ;
1194
1231
}
1195
1232
}
1196
1233
oparg = 0 ;
0 commit comments