25
25
package com .oracle .svm .core .deopt ;
26
26
27
27
import static com .oracle .svm .core .Uninterruptible .CALLED_FROM_UNINTERRUPTIBLE_CODE ;
28
+ import static com .oracle .svm .core .stack .JavaFrameAnchors .verifyTopFrameAnchor ;
28
29
29
30
import java .lang .annotation .ElementType ;
30
31
import java .lang .annotation .Retention ;
@@ -813,7 +814,7 @@ private static boolean isNonNullValue(UnsignedWord pointer) {
813
814
814
815
@ DeoptStub (stubType = StubType .LazyEntryStub )
815
816
@ Uninterruptible (reason = "Rewriting stack; gpReturnValue holds object reference." )
816
- public static UnsignedWord lazyDeoptStubObjectReturn (Pointer framePointer , UnsignedWord gpReturnValue , UnsignedWord fpReturnValue ) {
817
+ public static UnsignedWord lazyDeoptStubObjectReturn (Pointer originalStackPointer , UnsignedWord gpReturnValue , UnsignedWord fpReturnValue ) {
817
818
try {
818
819
assert PointerUtils .isAMultiple (KnownIntrinsics .readStackPointer (), Word .unsigned (ConfigurationValues .getTarget ().stackAlignment ));
819
820
assert Options .LazyDeoptimization .getValue ();
@@ -828,7 +829,7 @@ public static UnsignedWord lazyDeoptStubObjectReturn(Pointer framePointer, Unsig
828
829
gpReturnValueObject = ((Pointer ) gpReturnValue ).toObject ();
829
830
}
830
831
831
- lazyDeoptStubCore (framePointer , gpReturnValue , fpReturnValue , hasException , gpReturnValueObject );
832
+ lazyDeoptStubCore (originalStackPointer , gpReturnValue , fpReturnValue , hasException , gpReturnValueObject );
832
833
throw UnreachableNode .unreachable ();
833
834
834
835
} catch (Throwable t ) {
@@ -838,7 +839,7 @@ public static UnsignedWord lazyDeoptStubObjectReturn(Pointer framePointer, Unsig
838
839
839
840
@ DeoptStub (stubType = StubType .LazyEntryStub )
840
841
@ Uninterruptible (reason = "Rewriting stack." )
841
- public static UnsignedWord lazyDeoptStubPrimitiveReturn (Pointer framePointer , UnsignedWord gpReturnValue , UnsignedWord fpReturnValue ) {
842
+ public static UnsignedWord lazyDeoptStubPrimitiveReturn (Pointer originalStackPointer , UnsignedWord gpReturnValue , UnsignedWord fpReturnValue ) {
842
843
/*
843
844
* Note: when we dispatch an exception, we enter lazyDeoptStubObjectReturn instead, since
844
845
* that involves returning an exception object.
@@ -849,7 +850,7 @@ public static UnsignedWord lazyDeoptStubPrimitiveReturn(Pointer framePointer, Un
849
850
assert VMThreads .StatusSupport .isStatusJava () : "Deopt stub execution must not be visible to other threads." ;
850
851
assert !ExceptionUnwind .getLazyDeoptStubShouldReturnToExceptionHandler ();
851
852
852
- lazyDeoptStubCore (framePointer , gpReturnValue , fpReturnValue , false , null );
853
+ lazyDeoptStubCore (originalStackPointer , gpReturnValue , fpReturnValue , false , null );
853
854
throw UnreachableNode .unreachable ();
854
855
855
856
} catch (Throwable t ) {
@@ -864,32 +865,32 @@ public static UnsignedWord lazyDeoptStubPrimitiveReturn(Pointer framePointer, Un
864
865
* the code info, and construct the {@link DeoptimizedFrame}.
865
866
*/
866
867
@ Uninterruptible (reason = "Rewriting stack." )
867
- private static UnsignedWord lazyDeoptStubCore (Pointer framePointer , UnsignedWord gpReturnValue , UnsignedWord fpReturnValue , boolean hasException , Object gpReturnValueObject ) {
868
- CodePointer deoptStubAddress = FrameAccess .singleton ().readReturnAddress (CurrentIsolate .getCurrentThread (), framePointer );
868
+ private static UnsignedWord lazyDeoptStubCore (Pointer originalStackPointer , UnsignedWord gpReturnValue , UnsignedWord fpReturnValue , boolean hasException , Object gpReturnValueObject ) {
869
+ CodePointer deoptStubAddress = FrameAccess .singleton ().readReturnAddress (CurrentIsolate .getCurrentThread (), originalStackPointer );
869
870
assert isLazyDeoptStub (deoptStubAddress );
870
871
871
872
/* The original return address is at offset 0 from the stack pointer */
872
- CodePointer originalReturnAddress = framePointer .readWord (0 );
873
+ CodePointer originalReturnAddress = originalStackPointer .readWord (0 );
873
874
VMError .guarantee (originalReturnAddress .isNonNull ());
874
875
875
876
DeoptimizedFrame deoptFrame ;
876
877
try {
877
- deoptFrame = constructLazilyDeoptimizedFrameInterruptibly (framePointer , originalReturnAddress , hasException );
878
+ deoptFrame = constructLazilyDeoptimizedFrameInterruptibly (originalStackPointer , originalReturnAddress , hasException );
878
879
} catch (OutOfMemoryError ex ) {
879
880
/*
880
881
* If a OutOfMemoryError occurs during lazy deoptimization, we cannot let the frame
881
882
* being deoptimized handle the exception, because it might have been invalidated due to
882
883
* incorrect assumptions. Note that since unwindExceptionSkippingCaller does not return,
883
884
* this try...catch must not have a finally block, as it will not be executed.
884
885
*/
885
- ExceptionUnwind .unwindExceptionSkippingCaller (ex , framePointer );
886
+ ExceptionUnwind .unwindExceptionSkippingCaller (ex , originalStackPointer );
886
887
throw UnreachableNode .unreachable ();
887
888
}
888
889
889
890
DeoptimizationCounters .counters ().deoptCount .inc ();
890
891
VMError .guarantee (deoptFrame != null , "was not able to lazily construct a deoptimized frame" );
891
892
892
- Pointer newSp = computeNewFramePointer ( framePointer , deoptFrame );
893
+ Pointer newSp = computeNewStackPointer ( originalStackPointer , deoptFrame );
893
894
894
895
/* Build the content of the deopt target stack frames. */
895
896
deoptFrame .buildContent (newSp );
@@ -900,9 +901,9 @@ private static UnsignedWord lazyDeoptStubCore(Pointer framePointer, UnsignedWord
900
901
* can only be called from the current thread. Thus, there is no use case for eager
901
902
* deoptimization to happen if the current thread is executing the lazy deopt stub.
902
903
*/
903
- VMError .guarantee (framePointer .readWord (0 ) == originalReturnAddress , "Eager deoptimization should not occur when lazy deoptimization is in progress" );
904
+ VMError .guarantee (originalStackPointer .readWord (0 ) == originalReturnAddress , "Eager deoptimization should not occur when lazy deoptimization is in progress" );
904
905
905
- CodePointer returnAddressAfter = FrameAccess .singleton ().readReturnAddress (CurrentIsolate .getCurrentThread (), framePointer );
906
+ CodePointer returnAddressAfter = FrameAccess .singleton ().readReturnAddress (CurrentIsolate .getCurrentThread (), originalStackPointer );
906
907
VMError .guarantee (returnAddressAfter == deoptStubAddress , "Return address must remain unchanged during deoptimization" );
907
908
908
909
recentDeoptimizationEvents .append (deoptFrame .getCompletedMessage ());
@@ -962,7 +963,7 @@ private static DeoptimizedFrame constructLazilyDeoptimizedFrameInterruptibly0(Po
962
963
* When {@link #eagerDeoptStub} is "called", the stack looks like this:
963
964
*
964
965
* <pre>
965
- * : :
966
+ * : : highest stack address
966
967
* | |
967
968
* | | frame of the
968
969
* +--------------------------------+ deoptimized method
@@ -977,9 +978,8 @@ private static DeoptimizedFrame constructLazilyDeoptimizedFrameInterruptibly0(Po
977
978
* The instructions to compute the parameters must be generated in this method's prologue by a
978
979
* backend-specific FrameContext class.
979
980
*
980
- * @param framePointer This is a pointer to the reference which was written in
981
- * {@link #deoptimizeInRange} on the stack (the slot above the original return
982
- * address).
981
+ * @param originalStackPointer the original stack pointer of the deoptimized method (points to
982
+ * the {@link DeoptimizedFrame} object).
983
983
* @param gpReturnValue This is the value which was stored in the general purpose return
984
984
* register when the deopt stub was reached. It must be restored to the register
985
985
* before completion of the stub.
@@ -989,18 +989,19 @@ private static DeoptimizedFrame constructLazilyDeoptimizedFrameInterruptibly0(Po
989
989
*/
990
990
@ DeoptStub (stubType = StubType .EagerEntryStub )
991
991
@ Uninterruptible (reason = "Frame holds Objects in unmanaged storage." )
992
- public static UnsignedWord eagerDeoptStub (Pointer framePointer , UnsignedWord gpReturnValue , UnsignedWord fpReturnValue ) {
992
+ public static UnsignedWord eagerDeoptStub (Pointer originalStackPointer , UnsignedWord gpReturnValue , UnsignedWord fpReturnValue ) {
993
993
try {
994
994
assert PointerUtils .isAMultiple (KnownIntrinsics .readStackPointer (), Word .unsigned (ConfigurationValues .getTarget ().stackAlignment ));
995
995
VMError .guarantee (VMThreads .StatusSupport .isStatusJava (), "Deopt stub execution must not be visible to other threads." );
996
- DeoptimizedFrame frame = (DeoptimizedFrame ) ReferenceAccess .singleton ().readObjectAt (framePointer , true );
996
+
997
+ DeoptimizedFrame frame = (DeoptimizedFrame ) ReferenceAccess .singleton ().readObjectAt (originalStackPointer , true );
997
998
998
999
DeoptimizationCounters .counters ().deoptCount .inc ();
999
1000
if (DeoptimizationCounters .Options .ProfileDeoptimization .getValue ()) {
1000
1001
DeoptimizationCounters .startTime .set (System .nanoTime ());
1001
1002
}
1002
1003
1003
- final Pointer newSp = computeNewFramePointer ( framePointer , frame );
1004
+ final Pointer newSp = computeNewStackPointer ( originalStackPointer , frame );
1004
1005
1005
1006
/* Build the content of the deopt target stack frames. */
1006
1007
frame .buildContent (newSp );
@@ -1023,13 +1024,15 @@ public static UnsignedWord eagerDeoptStub(Pointer framePointer, UnsignedWord gpR
1023
1024
}
1024
1025
1025
1026
@ Uninterruptible (reason = CALLED_FROM_UNINTERRUPTIBLE_CODE , mayBeInlined = true )
1026
- private static Pointer computeNewFramePointer (Pointer originalFramePointer , DeoptimizedFrame deoptimizedFrame ) {
1027
- /* Computation of the new stack pointer: we start with the stack pointer of this frame. */
1028
- return originalFramePointer
1029
- /* Remove the size of the frame that gets deoptimized. */
1030
- .add (Word .unsigned (deoptimizedFrame .getSourceTotalFrameSize ()))
1031
- /* Add the size of the deoptimization target frames. */
1032
- .subtract (deoptimizedFrame .getTargetContent ().getSize ());
1027
+ private static Pointer computeNewStackPointer (Pointer originalStackPointer , DeoptimizedFrame deoptimizedFrame ) {
1028
+ /* Remove the size of the frame that gets deoptimized. */
1029
+ Pointer callerStackPointer = originalStackPointer .add (Word .unsigned (deoptimizedFrame .getSourceTotalFrameSize ()));
1030
+
1031
+ /* Verify that the top frame anchor is in a part of the stack that is not rewritten. */
1032
+ verifyTopFrameAnchor (callerStackPointer );
1033
+
1034
+ /* Add the size of the deoptimization target frames. */
1035
+ return callerStackPointer .subtract (deoptimizedFrame .getTargetContent ().getSize ());
1033
1036
}
1034
1037
1035
1038
/**
@@ -1054,7 +1057,6 @@ private static UnsignedWord rewriteStackStub(Pointer newSp, UnsignedWord gpRetur
1054
1057
if (DeoptimizationCounters .Options .ProfileDeoptimization .getValue ()) {
1055
1058
DeoptimizationCounters .counters ().timeSpentInDeopt .add (System .nanoTime () - DeoptimizationCounters .startTime .get ());
1056
1059
}
1057
-
1058
1060
return gpReturnValue ;
1059
1061
}
1060
1062
0 commit comments