< prev index next >

src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp

Print this page
@@ -65,19 +65,25 @@
    address sender_pc = ContinuationHelper::return_address_at(sender_sp - 1);
    assert(sender_sp != f.sp(), "must have changed");
  
    int slot = 0;
    CodeBlob* sender_cb = CodeCache::find_blob_and_oopmap(sender_pc, slot);
+ 
+   // Repair the sender sp if the frame has been extended
+   if (sender_cb->is_nmethod()) {
+     sender_sp = f.repair_sender_sp(sender_sp, link_addr);
+   }
+ 
    return sender_cb != nullptr
      ? frame(sender_sp, sender_sp, *link_addr, sender_pc, sender_cb,
              slot == -1 ? nullptr : sender_cb->oop_map_for_slot(slot, sender_pc),
              false /* on_heap ? */)
      : frame(sender_sp, sender_sp, *link_addr, sender_pc);
  }
  
  template<typename FKind>
- frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
+ frame FreezeBase::new_heap_frame(frame& f, frame& caller, int size_adjust) {
    assert(FKind::is_instance(f), "");
    assert(!caller.is_interpreted_frame()
      || caller.unextended_sp() == (intptr_t*)caller.at(frame::interpreter_frame_last_sp_offset), "");
  
    intptr_t *sp, *fp; // sp is really our unextended_sp

@@ -104,12 +110,12 @@
      // We need to re-read fp out of the frame because it may be an oop and we might have
      // had a safepoint in finalize_freeze, after constructing f.
      fp = *(intptr_t**)(f.sp() - frame::sender_sp_offset);
  
      int fsize = FKind::size(f);
-     sp = caller.unextended_sp() - fsize;
-     if (caller.is_interpreted_frame()) {
+     sp = caller.unextended_sp() - fsize - size_adjust;
+     if (caller.is_interpreted_frame() && size_adjust == 0) {
        // If the caller is interpreted, our stackargs are not supposed to overlap with it
        // so we make more room by moving sp down by argsize
        int argsize = FKind::stack_argsize(f);
        sp -= argsize;
      }

@@ -178,15 +184,16 @@
    intptr_t* fp_addr = hf.sp() - frame::sender_sp_offset;
    *fp_addr = hf.is_interpreted_frame() ? (intptr_t)(hf.fp() - fp_addr)
                                         : (intptr_t)hf.fp();
  }
  
- inline void FreezeBase::patch_pd(frame& hf, const frame& caller) {
+ inline void FreezeBase::patch_pd(frame& hf, const frame& caller, bool is_bottom_frame) {
    if (caller.is_interpreted_frame()) {
      assert(!caller.is_empty(), "");
      patch_callee_link_relative(caller, caller.fp());
-   } else {
+   } else if (is_bottom_frame && caller.pc() != nullptr) {
+     assert(caller.is_compiled_frame(), "");
      // If we're the bottom-most frame frozen in this freeze, the caller might have stayed frozen in the chunk,
      // and its oop-containing fp fixed. We've now just overwritten it, so we must patch it back to its value
      // as read from the chunk.
      patch_callee_link(caller, caller.fp());
    }

@@ -213,11 +220,11 @@
  inline frame ThawBase::new_entry_frame() {
    intptr_t* sp = _cont.entrySP();
    return frame(sp, sp, _cont.entryFP(), _cont.entryPC()); // TODO PERF: This finds code blob and computes deopt state
  }
  
- template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame& caller, bool bottom) {
+ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame& caller, bool bottom, int size_adjust) {
    assert(FKind::is_instance(hf), "");
    // The values in the returned frame object will be written into the callee's stack in patch.
  
    if (FKind::interpreted) {
      intptr_t* heap_sp = hf.unextended_sp();

@@ -241,28 +248,27 @@
      *f.addr_at(frame::interpreter_frame_locals_offset) = *hf.addr_at(frame::interpreter_frame_locals_offset);
      assert((intptr_t)f.fp() % frame::frame_alignment == 0, "");
      return f;
    } else {
      int fsize = FKind::size(hf);
-     intptr_t* frame_sp = caller.unextended_sp() - fsize;
+     intptr_t* frame_sp = caller.unextended_sp() - fsize - size_adjust;
      if (bottom || caller.is_interpreted_frame()) {
-       int argsize = FKind::stack_argsize(hf);
- 
-       fsize += argsize;
-       frame_sp   -= argsize;
-       caller.set_sp(caller.sp() - argsize);
-       assert(caller.sp() == frame_sp + (fsize-argsize), "");
- 
+       if (size_adjust == 0) {
+         int argsize = FKind::stack_argsize(hf);
+         frame_sp -= argsize;
+       }
        frame_sp = align(hf, frame_sp, caller, bottom);
      }
+     caller.set_sp(frame_sp + fsize);
+     assert(is_aligned(frame_sp, frame::frame_alignment), "");
  
      assert(hf.cb() != nullptr, "");
      assert(hf.oop_map() != nullptr, "");
      intptr_t* fp;
      if (PreserveFramePointer) {
        // we need to recreate a "real" frame pointer, pointing into the stack
-       fp = frame_sp + FKind::size(hf) - frame::sender_sp_offset;
+       fp = frame_sp + fsize - frame::sender_sp_offset;
      } else {
        fp = FKind::stub || FKind::native
          ? frame_sp + fsize - frame::sender_sp_offset // fp always points to the address below the pushed return pc. We need correct address.
          : *(intptr_t**)(hf.sp() - frame::sender_sp_offset); // we need to re-read fp because it may be an oop and we might have fixed the frame.
      }

@@ -273,20 +279,20 @@
  inline intptr_t* ThawBase::align(const frame& hf, intptr_t* frame_sp, frame& caller, bool bottom) {
  #ifdef _LP64
    if (((intptr_t)frame_sp & 0xf) != 0) {
      assert(caller.is_interpreted_frame() || (bottom && hf.compiled_frame_stack_argsize() % 2 != 0), "");
      frame_sp--;
-     caller.set_sp(caller.sp() - 1);
    }
    assert(is_aligned(frame_sp, frame::frame_alignment), "");
  #endif
- 
    return frame_sp;
  }
  
  inline void ThawBase::patch_pd(frame& f, const frame& caller) {
-   patch_callee_link(caller, caller.fp());
+   if (caller.is_interpreted_frame() || PreserveFramePointer) {
+     patch_callee_link(caller, caller.fp());
+   }
  }
  
  inline void ThawBase::patch_pd(frame& f, intptr_t* caller_sp) {
    intptr_t* fp = caller_sp - frame::sender_sp_offset;
    patch_callee_link(f, fp);
< prev index next >