< prev index next >

src/hotspot/cpu/x86/frame_x86.cpp

Print this page
*** 143,17 ***
        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;
        // On Intel the return_address is always the word on the stack
        sender_pc = (address) *(sender_sp-1);
        // Note: frame::sender_sp_offset is only valid for compiled frame
!       saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
!     }
  
      if (Continuation::is_return_barrier_entry(sender_pc)) {
        // sender_pc might be invalid so check that the frame
        // actually belongs to a Continuation.
        if (!Continuation::is_frame_in_continuation(thread, *this)) {
          return false;
--- 143,20 ---
        sender_sp = _unextended_sp + _cb->frame_size();
        // Is sender_sp safe?
        if (!thread->is_in_full_stack_checked((address)sender_sp)) {
          return false;
        }
        // On Intel the return_address is always the word on the stack
        sender_pc = (address) *(sender_sp-1);
        // Note: frame::sender_sp_offset is only valid for compiled frame
!       intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset);
!       saved_fp = *saved_fp_addr;
  
+       // 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)) {
        // sender_pc might be invalid so check that the frame
        // actually belongs to a Continuation.
        if (!Continuation::is_frame_in_continuation(thread, *this)) {
          return false;

*** 671,10 ***
--- 674,13 ---
        ret_pc_loc = fp() + return_addr_offset;
        fp_loc = fp();
      } else {
        ret_pc_loc = real_fp() - return_addr_offset;
        fp_loc = real_fp() - sender_sp_offset;
+       if (cb()->is_nmethod() && cb()->as_nmethod_or_null()->needs_stack_repair()) {
+         values.describe(frame_no, fp_loc - 1, err_msg("fsize for #%d", frame_no), 1);
+       }
      }
      address ret_pc = *(address*)ret_pc_loc;
      values.describe(frame_no, ret_pc_loc,
        Continuation::is_return_barrier_entry(ret_pc) ? "return address (return barrier)" : "return address");
      values.describe(-1, fp_loc, "saved fp", 0); // "unowned" as value belongs to sender

*** 694,10 ***
--- 700,47 ---
    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 {
+   nmethod* nm = _cb->as_nmethod_or_null();
+   if (nm != nullptr && nm->needs_stack_repair()) {
+     // The stack increment resides just below the saved rbp on the stack
+     // and does not account for the return address.
+     intptr_t* real_frame_size_addr = (intptr_t*) (saved_fp_addr - 1);
+     int real_frame_size = ((*real_frame_size_addr) + wordSize) / wordSize;
+     assert(real_frame_size >= _cb->frame_size() && real_frame_size <= 1000000, "invalid frame size");
+     sender_sp = unextended_sp() + real_frame_size;
+   }
+   return sender_sp;
+ }
+ 
+ intptr_t* frame::repair_sender_sp(nmethod* nm, intptr_t* sp, intptr_t** saved_fp_addr) {
+   assert(nm != nullptr && nm->needs_stack_repair(), "");
+   // The stack increment resides just below the saved rbp on the stack
+   // and does not account for the return address.
+   intptr_t* real_frame_size_addr = (intptr_t*) (saved_fp_addr - 1);
+   int real_frame_size = ((*real_frame_size_addr) + wordSize) / wordSize;
+   assert(real_frame_size >= nm->frame_size() && real_frame_size <= 1000000, "invalid frame size");
+   return sp + real_frame_size;
+ }
+ 
+ bool frame::was_augmented_on_entry(int& real_size) const {
+   assert(is_compiled_frame(), "");
+   if (_cb->as_nmethod_or_null()->needs_stack_repair()) {
+     intptr_t* real_frame_size_addr = unextended_sp() + _cb->frame_size() - sender_sp_offset - 1;
+     log_trace(continuations)("real_frame_size is addr is " INTPTR_FORMAT, p2i(real_frame_size_addr));
+     real_size = ((*real_frame_size_addr) + wordSize) / wordSize;
+     return real_size != _cb->frame_size();
+   }
+   real_size = _cb->frame_size();
+   return false;
+ }
+ 
  void JavaFrameAnchor::make_walkable() {
    // last frame set?
    if (last_Java_sp() == nullptr) return;
    // already walkable?
    if (walkable()) return;
< prev index next >