< prev index next > src/hotspot/cpu/x86/continuationFreezeThaw_x86.inline.hpp
Print this page
address sender_pc = (address) *(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)
: 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
// 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;
}
*fp_addr = hf.is_interpreted_frame() ? (intptr_t)(hf.fp() - fp_addr)
: (intptr_t)hf.fp();
assert(frame_pc == ContinuationHelper::Frame::real_pc(hf), "");
}
- 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());
}
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();
// copy relativized locals from the heap frame
*f.addr_at(frame::interpreter_frame_locals_offset) = locals_offset;
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.
}
inline intptr_t* ThawBase::align(const frame& hf, intptr_t* frame_sp, frame& caller, bool bottom) {
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), "");
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 >