< prev index next >

src/hotspot/cpu/x86/frame_x86.cpp

Print this page
@@ -143,17 +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;
        }
-       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);
-     }
+       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;

@@ -608,17 +611,28 @@
      intptr_t* fp_loc;
      if (is_interpreted_frame()) {
        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, real_fp() - sender_sp_offset - 1, err_msg("fsize for #%d", frame_no), 1);
+       }
+       frame::CompiledFramePointers cfp = compiled_frame_details();
+       ret_pc_loc = (intptr_t*)cfp.sender_pc_addr;
+       fp_loc = (intptr_t*)cfp.saved_fp_addr;
      }
      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
+ 
+     intptr_t* ret_pc_loc2 = real_fp() - return_addr_offset;
+     if (ret_pc_loc2 != ret_pc_loc) {
+       intptr_t* fp_loc2 = real_fp() - sender_sp_offset;
+       values.describe(frame_no, ret_pc_loc2, "return address copy #2");
+       values.describe(-1, fp_loc2, "saved fp copy #2", 0);
+     }
    }
  }
  
  #endif // !PRODUCT
  

@@ -633,10 +647,68 @@
    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 and rbp (see MacroAssembler::remove_frame).
+     intptr_t* real_frame_size_addr = (intptr_t*) (saved_fp_addr - 1);
+     int real_frame_size = (*real_frame_size_addr / wordSize) + metadata_words_at_bottom;
+     assert(real_frame_size >= _cb->frame_size() && real_frame_size <= 1000000, "invalid frame size");
+     sender_sp = unextended_sp() + real_frame_size;
+   }
+   return sender_sp;
+ }
+ 
+ 
+ // See comment in MacroAssembler::remove_frame
+ frame::CompiledFramePointers frame::compiled_frame_details() const {
+   // frame owned by optimizing compiler
+   assert(_cb->frame_size() > 0, "must have non-zero frame size");
+   intptr_t* sender_sp = unextended_sp() + _cb->frame_size();
+   assert(sender_sp == real_fp(), "");
+ 
+   // Repair the sender sp if the frame has been extended
+   sender_sp = repair_sender_sp(sender_sp, (intptr_t**)(sender_sp - frame::sender_sp_offset));
+ 
+   CompiledFramePointers cfp;
+   cfp.sender_sp = sender_sp;
+   cfp.saved_fp_addr = (intptr_t**)(sender_sp - frame::sender_sp_offset);
+   // On Intel the return_address is always the word on the stack
+   cfp.sender_pc_addr = (address*)(sender_sp - frame::return_addr_offset);
+ 
+   return cfp;
+ }
+ 
+ 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 and rbp (see MacroAssembler::remove_frame).
+   intptr_t* real_frame_size_addr = (intptr_t*) (saved_fp_addr - 1);
+   int real_frame_size = (*real_frame_size_addr / wordSize) + metadata_words_at_bottom;
+   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()) {
+     // The stack increment resides just below the saved rbp on the stack
+     // and does not account for the return address and rbp (see MacroAssembler::remove_frame).
+     intptr_t* real_frame_size_addr = unextended_sp() + _cb->frame_size() - sender_sp_offset - 1;
+     real_size = (*real_frame_size_addr / wordSize) + metadata_words_at_bottom;
+     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 >