< prev index next >

src/hotspot/cpu/aarch64/frame_aarch64.cpp

Print this page
@@ -152,18 +152,21 @@
        sender_sp = _unextended_sp + _cb->frame_size();
        // Is sender_sp safe?
        if (!thread->is_in_full_stack_checked((address)sender_sp)) {
          return false;
        }
-       sender_unextended_sp = sender_sp;
        // Note: frame::sender_sp_offset is only valid for compiled frame
-       saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
+       intptr_t **saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset);
+       saved_fp = *saved_fp_addr;
        // Note: PAC authentication may fail in case broken frame is passed in.
        // Just strip it for now.
        sender_pc = pauth_strip_pointer((address) *(sender_sp - 1));
-     }
  
+       // Repair the sender sp if this is a method with scalarized inline type args
+       sender_sp = repair_sender_sp(sender_sp, saved_fp_addr);
+       sender_unextended_sp = sender_sp;
+     }
      if (Continuation::is_return_barrier_entry(sender_pc)) {
        // If our sender_pc is the return barrier, then our "real" sender is the continuation entry
        frame s = Continuation::continuation_bottom_sender(thread, *this, sender_sp);
        sender_sp = s.sp();
        sender_pc = s.pc();

@@ -786,10 +789,26 @@
    init((intptr_t*)sp, (intptr_t*)fp, (address)pc);
  }
  
  #endif
  
+ // Check for a method with scalarized inline type arguments that needs
+ // a stack repair and return the repaired sender stack pointer.
+ intptr_t* frame::repair_sender_sp(intptr_t* sender_sp, intptr_t** saved_fp_addr) const {
+   CompiledMethod* cm = _cb->as_compiled_method_or_null();
+   if (cm != nullptr && cm->needs_stack_repair()) {
+     // The stack increment resides just below the saved FP on the stack and
+     // records the total frame size excluding the two words for saving FP and LR.
+     intptr_t* sp_inc_addr = (intptr_t*) (saved_fp_addr - 1);
+     assert(*sp_inc_addr % StackAlignmentInBytes == 0, "sp_inc not aligned");
+     int real_frame_size = (*sp_inc_addr / wordSize) + 2;
+     assert(real_frame_size >= _cb->frame_size() && real_frame_size <= 1000000, "invalid frame size");
+     sender_sp = unextended_sp() + real_frame_size;
+   }
+   return sender_sp;
+ }
+ 
  void JavaFrameAnchor::make_walkable() {
    // last frame set?
    if (last_Java_sp() == nullptr) return;
    // already walkable?
    if (walkable()) return;
< prev index next >