8308984: Relativize last_sp (and top_frame_sp) in interpreter frames
Reviewed-by: pchilanomate, aph, haosun
This commit is contained in:
parent
fdac6a6ac8
commit
c36e009772
src/hotspot
cpu
aarch64
continuationFreezeThaw_aarch64.inline.hppcontinuationHelper_aarch64.inline.hppframe_aarch64.cppframe_aarch64.inline.hppinterp_masm_aarch64.cpptemplateInterpreterGenerator_aarch64.cpp
ppc
continuationFreezeThaw_ppc.inline.hppcontinuationHelper_ppc.inline.hppframe_ppc.inline.hppinterp_masm_ppc_64.cpptemplateInterpreterGenerator_ppc.cpp
riscv
continuationFreezeThaw_riscv.inline.hppcontinuationHelper_riscv.inline.hppframe_riscv.cppframe_riscv.inline.hppinterp_masm_riscv.cpptemplateInterpreterGenerator_riscv.cpp
x86
share/runtime
@ -83,7 +83,7 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
|
||||
intptr_t *sp, *fp; // sp is really our unextended_sp
|
||||
if (FKind::interpreted) {
|
||||
assert((intptr_t*)f.at(frame::interpreter_frame_last_sp_offset) == nullptr
|
||||
|| f.unextended_sp() == (intptr_t*)f.at(frame::interpreter_frame_last_sp_offset), "");
|
||||
|| f.unextended_sp() == (intptr_t*)f.at_relative(frame::interpreter_frame_last_sp_offset), "");
|
||||
intptr_t locals_offset = *f.addr_at(frame::interpreter_frame_locals_offset);
|
||||
// If the caller.is_empty(), i.e. we're freezing into an empty chunk, then we set
|
||||
// the chunk's argsize in finalize_freeze and make room for it above the unextended_sp
|
||||
@ -123,7 +123,7 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
|
||||
|
||||
void FreezeBase::adjust_interpreted_frame_unextended_sp(frame& f) {
|
||||
assert((f.at(frame::interpreter_frame_last_sp_offset) != 0) || (f.unextended_sp() == f.sp()), "");
|
||||
intptr_t* real_unextended_sp = (intptr_t*)f.at(frame::interpreter_frame_last_sp_offset);
|
||||
intptr_t* real_unextended_sp = (intptr_t*)f.at_relative_or_null(frame::interpreter_frame_last_sp_offset);
|
||||
if (real_unextended_sp != nullptr) {
|
||||
f.set_unextended_sp(real_unextended_sp); // can be null at a safepoint
|
||||
}
|
||||
@ -149,8 +149,8 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
|
||||
// because we freeze the padding word (see recurse_freeze_interpreted_frame) in order to keep the same relativized
|
||||
// locals value, we don't need to change the locals value here.
|
||||
|
||||
// at(frame::interpreter_frame_last_sp_offset) can be null at safepoint preempts
|
||||
*hf.addr_at(frame::interpreter_frame_last_sp_offset) = hf.unextended_sp() - hf.fp();
|
||||
// Make sure that last_sp is already relativized.
|
||||
assert((intptr_t*)hf.at_relative(frame::interpreter_frame_last_sp_offset) == hf.unextended_sp(), "");
|
||||
|
||||
relativize_one(vfp, hfp, frame::interpreter_frame_initial_sp_offset); // == block_top == block_bottom
|
||||
relativize_one(vfp, hfp, frame::interpreter_frame_extended_sp_offset);
|
||||
@ -290,7 +290,9 @@ static inline void derelativize_one(intptr_t* const fp, int offset) {
|
||||
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
|
||||
intptr_t* vfp = f.fp();
|
||||
|
||||
derelativize_one(vfp, frame::interpreter_frame_last_sp_offset);
|
||||
// Make sure that last_sp is kept relativized.
|
||||
assert((intptr_t*)f.at_relative(frame::interpreter_frame_last_sp_offset) == f.unextended_sp(), "");
|
||||
|
||||
derelativize_one(vfp, frame::interpreter_frame_initial_sp_offset);
|
||||
derelativize_one(vfp, frame::interpreter_frame_extended_sp_offset);
|
||||
}
|
||||
|
@ -125,7 +125,8 @@ inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f,
|
||||
assert(res == (intptr_t*)f.interpreter_frame_monitor_end() - expression_stack_sz, "");
|
||||
assert(res >= f.unextended_sp(),
|
||||
"res: " INTPTR_FORMAT " initial_sp: " INTPTR_FORMAT " last_sp: " INTPTR_FORMAT " unextended_sp: " INTPTR_FORMAT " expression_stack_size: %d",
|
||||
p2i(res), p2i(f.addr_at(frame::interpreter_frame_initial_sp_offset)), f.at(frame::interpreter_frame_last_sp_offset), p2i(f.unextended_sp()), expression_stack_sz);
|
||||
p2i(res), p2i(f.addr_at(frame::interpreter_frame_initial_sp_offset)), f.at_relative_or_null(frame::interpreter_frame_last_sp_offset),
|
||||
p2i(f.unextended_sp()), expression_stack_sz);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -355,7 +355,9 @@ void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
|
||||
|
||||
// Used by template based interpreter deoptimization
|
||||
void frame::interpreter_frame_set_last_sp(intptr_t* sp) {
|
||||
*((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp;
|
||||
assert(is_interpreted_frame(), "interpreted frame expected");
|
||||
// set relativized last_sp
|
||||
ptr_at_put(interpreter_frame_last_sp_offset, sp != nullptr ? (sp - fp()) : 0);
|
||||
}
|
||||
|
||||
// Used by template based interpreter deoptimization
|
||||
|
@ -262,7 +262,9 @@ inline intptr_t* frame::interpreter_frame_locals() const {
|
||||
}
|
||||
|
||||
inline intptr_t* frame::interpreter_frame_last_sp() const {
|
||||
return (intptr_t*)at(interpreter_frame_last_sp_offset);
|
||||
intptr_t n = *addr_at(interpreter_frame_last_sp_offset);
|
||||
assert(n <= 0, "n: " INTPTR_FORMAT, n);
|
||||
return n != 0 ? &fp()[n] : nullptr;
|
||||
}
|
||||
|
||||
inline intptr_t* frame::interpreter_frame_bcp_addr() const {
|
||||
|
@ -430,7 +430,9 @@ void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
|
||||
// set sender sp
|
||||
mov(r19_sender_sp, sp);
|
||||
// record last_sp
|
||||
str(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
sub(rscratch1, esp, rfp);
|
||||
asr(rscratch1, rscratch1, Interpreter::logStackElementSize);
|
||||
str(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
}
|
||||
|
||||
// Jump to from_interpreted entry of a call unless single stepping is possible
|
||||
|
@ -465,7 +465,8 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
address entry = __ pc();
|
||||
|
||||
// Restore stack bottom in case i2c adjusted stack
|
||||
__ ldr(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ ldr(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ lea(esp, Address(rfp, rscratch1, Address::lsl(Interpreter::logStackElementSize)));
|
||||
// and null it as marker that esp is now tos until next java call
|
||||
__ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ restore_bcp();
|
||||
@ -521,7 +522,8 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state,
|
||||
__ restore_sp_after_call(); // Restore SP to extended SP
|
||||
|
||||
// Restore expression stack pointer
|
||||
__ ldr(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ ldr(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ lea(esp, Address(rfp, rscratch1, Address::lsl(Interpreter::logStackElementSize)));
|
||||
// null last_sp until next java call
|
||||
__ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
|
||||
@ -1867,7 +1869,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
/* notify_jvmdi */ false);
|
||||
|
||||
// Restore the last_sp and null it out
|
||||
__ ldr(esp, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ ldr(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ lea(esp, Address(rfp, rscratch1, Address::lsl(Interpreter::logStackElementSize)));
|
||||
__ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
|
||||
__ restore_bcp();
|
||||
|
@ -89,7 +89,7 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
|
||||
|
||||
relativize_one(vfp, hfp, ijava_idx(monitors));
|
||||
relativize_one(vfp, hfp, ijava_idx(esp));
|
||||
relativize_one(vfp, hfp, ijava_idx(top_frame_sp));
|
||||
// top_frame_sp is already relativized
|
||||
|
||||
// hfp == hf.sp() + (f.fp() - f.sp()) is not true on ppc because the stack frame has room for
|
||||
// the maximal expression stack and the expression stack in the heap frame is trimmed.
|
||||
@ -544,7 +544,7 @@ inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, c
|
||||
|
||||
derelativize_one(vfp, ijava_idx(monitors));
|
||||
derelativize_one(vfp, ijava_idx(esp));
|
||||
derelativize_one(vfp, ijava_idx(top_frame_sp));
|
||||
// Keep top_frame_sp relativized.
|
||||
}
|
||||
|
||||
inline void ThawBase::patch_pd(frame& f, const frame& caller) {
|
||||
|
@ -86,7 +86,7 @@ inline void ContinuationHelper::InterpretedFrame::patch_sender_sp(frame& f, cons
|
||||
intptr_t* sp = caller.unextended_sp();
|
||||
if (!f.is_heap_frame() && caller.is_interpreted_frame()) {
|
||||
// See diagram "Interpreter Calling Procedure on PPC" at the end of continuationFreezeThaw_ppc.inline.hpp
|
||||
sp = (intptr_t*)caller.at(ijava_idx(top_frame_sp));
|
||||
sp = (intptr_t*)caller.at_relative(ijava_idx(top_frame_sp));
|
||||
}
|
||||
assert(f.is_interpreted_frame(), "");
|
||||
assert(f.is_heap_frame() || is_aligned(sp, frame::alignment_in_bytes), "");
|
||||
|
@ -231,7 +231,13 @@ inline intptr_t* frame::interpreter_frame_esp() const {
|
||||
inline void frame::interpreter_frame_set_monitor_end(BasicObjectLock* end) { get_ijava_state()->monitors = (intptr_t) end;}
|
||||
inline void frame::interpreter_frame_set_cpcache(ConstantPoolCache* cp) { *interpreter_frame_cache_addr() = cp; }
|
||||
inline void frame::interpreter_frame_set_esp(intptr_t* esp) { get_ijava_state()->esp = (intptr_t) esp; }
|
||||
inline void frame::interpreter_frame_set_top_frame_sp(intptr_t* top_frame_sp) { get_ijava_state()->top_frame_sp = (intptr_t) top_frame_sp; }
|
||||
|
||||
inline void frame::interpreter_frame_set_top_frame_sp(intptr_t* top_frame_sp) {
|
||||
assert(is_interpreted_frame(), "interpreted frame expected");
|
||||
// set relativized top_frame_sp
|
||||
get_ijava_state()->top_frame_sp = (intptr_t) (top_frame_sp - fp());
|
||||
}
|
||||
|
||||
inline void frame::interpreter_frame_set_sender_sp(intptr_t* sender_sp) { get_ijava_state()->sender_sp = (intptr_t) sender_sp; }
|
||||
|
||||
inline intptr_t* frame::interpreter_frame_expression_stack() const {
|
||||
|
@ -1241,6 +1241,9 @@ void InterpreterMacroAssembler::call_from_interpreter(Register Rtarget_method, R
|
||||
save_interpreter_state(Rscratch2);
|
||||
#ifdef ASSERT
|
||||
ld(Rscratch1, _ijava_state_neg(top_frame_sp), Rscratch2); // Rscratch2 contains fp
|
||||
sldi(Rscratch1, Rscratch1, Interpreter::logStackElementSize);
|
||||
add(Rscratch1, Rscratch1, Rscratch2); // Rscratch2 contains fp
|
||||
// Compare sender_sp with the derelativized top_frame_sp
|
||||
cmpd(CCR0, R21_sender_SP, Rscratch1);
|
||||
asm_assert_eq("top_frame_sp incorrect");
|
||||
#endif
|
||||
@ -2015,7 +2018,10 @@ void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Regist
|
||||
"size of a monitor must respect alignment of SP");
|
||||
|
||||
resize_frame(-monitor_size, /*temp*/esp); // Allocate space for new monitor
|
||||
std(R1_SP, _ijava_state_neg(top_frame_sp), esp); // esp contains fp
|
||||
subf(Rtemp2, esp, R1_SP); // esp contains fp
|
||||
sradi(Rtemp2, Rtemp2, Interpreter::logStackElementSize);
|
||||
// Store relativized top_frame_sp
|
||||
std(Rtemp2, _ijava_state_neg(top_frame_sp), esp); // esp contains fp
|
||||
|
||||
// Shuffle expression stack down. Recall that stack_base points
|
||||
// just above the new expression stack bottom. Old_tos and new_tos
|
||||
@ -2251,6 +2257,9 @@ void InterpreterMacroAssembler::restore_interpreter_state(Register scratch, bool
|
||||
Register tfsp = R18_locals;
|
||||
Register scratch2 = R26_monitor;
|
||||
ld(tfsp, _ijava_state_neg(top_frame_sp), scratch);
|
||||
// Derelativize top_frame_sp
|
||||
sldi(tfsp, tfsp, Interpreter::logStackElementSize);
|
||||
add(tfsp, tfsp, scratch);
|
||||
resize_frame_absolute(tfsp, scratch2, R0);
|
||||
}
|
||||
ld(R14_bcp, _ijava_state_neg(bcp), scratch); // Changed by VM code (exception).
|
||||
|
@ -1061,8 +1061,10 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
|
||||
__ std(R0, _ijava_state_neg(oop_tmp), R1_SP); // only used for native_call
|
||||
|
||||
// Store sender's SP and this frame's top SP.
|
||||
__ subf(R12_scratch2, Rtop_frame_size, R1_SP);
|
||||
__ std(R21_sender_SP, _ijava_state_neg(sender_sp), R1_SP);
|
||||
__ neg(R12_scratch2, Rtop_frame_size);
|
||||
__ sradi(R12_scratch2, R12_scratch2, Interpreter::logStackElementSize);
|
||||
// Store relativized top_frame_sp
|
||||
__ std(R12_scratch2, _ijava_state_neg(top_frame_sp), R1_SP);
|
||||
|
||||
// Push top frame.
|
||||
|
@ -82,7 +82,7 @@ template<typename FKind> frame FreezeBase::new_heap_frame(frame& f, frame& calle
|
||||
intptr_t *sp, *fp; // sp is really our unextended_sp
|
||||
if (FKind::interpreted) {
|
||||
assert((intptr_t*)f.at(frame::interpreter_frame_last_sp_offset) == nullptr
|
||||
|| f.unextended_sp() == (intptr_t*)f.at(frame::interpreter_frame_last_sp_offset), "");
|
||||
|| f.unextended_sp() == (intptr_t*)f.at_relative(frame::interpreter_frame_last_sp_offset), "");
|
||||
intptr_t locals_offset = *f.addr_at(frame::interpreter_frame_locals_offset);
|
||||
// If the caller.is_empty(), i.e. we're freezing into an empty chunk, then we set
|
||||
// the chunk's argsize in finalize_freeze and make room for it above the unextended_sp
|
||||
@ -121,7 +121,7 @@ template<typename FKind> frame FreezeBase::new_heap_frame(frame& f, frame& calle
|
||||
|
||||
void FreezeBase::adjust_interpreted_frame_unextended_sp(frame& f) {
|
||||
assert((f.at(frame::interpreter_frame_last_sp_offset) != 0) || (f.unextended_sp() == f.sp()), "");
|
||||
intptr_t* real_unextended_sp = (intptr_t*)f.at(frame::interpreter_frame_last_sp_offset);
|
||||
intptr_t* real_unextended_sp = (intptr_t*)f.at_relative_or_null(frame::interpreter_frame_last_sp_offset);
|
||||
if (real_unextended_sp != nullptr) {
|
||||
f.set_unextended_sp(real_unextended_sp); // can be null at a safepoint
|
||||
}
|
||||
@ -147,8 +147,8 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
|
||||
// because we freeze the padding word (see recurse_freeze_interpreted_frame) in order to keep the same relativized
|
||||
// locals value, we don't need to change the locals value here.
|
||||
|
||||
// at(frame::interpreter_frame_last_sp_offset) can be null at safepoint preempts
|
||||
*hf.addr_at(frame::interpreter_frame_last_sp_offset) = hf.unextended_sp() - hf.fp();
|
||||
// Make sure that last_sp is already relativized.
|
||||
assert((intptr_t*)hf.at_relative(frame::interpreter_frame_last_sp_offset) == hf.unextended_sp(), "");
|
||||
|
||||
relativize_one(vfp, hfp, frame::interpreter_frame_initial_sp_offset); // == block_top == block_bottom
|
||||
relativize_one(vfp, hfp, frame::interpreter_frame_extended_sp_offset);
|
||||
@ -292,7 +292,9 @@ static inline void derelativize_one(intptr_t* const fp, int offset) {
|
||||
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
|
||||
intptr_t* vfp = f.fp();
|
||||
|
||||
derelativize_one(vfp, frame::interpreter_frame_last_sp_offset);
|
||||
// Make sure that last_sp is kept relativized.
|
||||
assert((intptr_t*)f.at_relative(frame::interpreter_frame_last_sp_offset) == f.unextended_sp(), "");
|
||||
|
||||
derelativize_one(vfp, frame::interpreter_frame_initial_sp_offset);
|
||||
derelativize_one(vfp, frame::interpreter_frame_extended_sp_offset);
|
||||
}
|
||||
|
@ -125,7 +125,8 @@ inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f,
|
||||
assert(res == (intptr_t*)f.interpreter_frame_monitor_end() - expression_stack_sz, "");
|
||||
assert(res >= f.unextended_sp(),
|
||||
"res: " INTPTR_FORMAT " initial_sp: " INTPTR_FORMAT " last_sp: " INTPTR_FORMAT " unextended_sp: " INTPTR_FORMAT " expression_stack_size: %d",
|
||||
p2i(res), p2i(f.addr_at(frame::interpreter_frame_initial_sp_offset)), f.at(frame::interpreter_frame_last_sp_offset), p2i(f.unextended_sp()), expression_stack_sz);
|
||||
p2i(res), p2i(f.addr_at(frame::interpreter_frame_initial_sp_offset)), f.at_relative_or_null(frame::interpreter_frame_last_sp_offset),
|
||||
p2i(f.unextended_sp()), expression_stack_sz);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,9 @@ void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
|
||||
|
||||
// Used by template based interpreter deoptimization
|
||||
void frame::interpreter_frame_set_last_sp(intptr_t* last_sp) {
|
||||
*((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = last_sp;
|
||||
assert(is_interpreted_frame(), "interpreted frame expected");
|
||||
// set relativized last_sp
|
||||
ptr_at_put(interpreter_frame_last_sp_offset, last_sp != nullptr ? (last_sp - fp()) : 0);
|
||||
}
|
||||
|
||||
void frame::interpreter_frame_set_extended_sp(intptr_t* sp) {
|
||||
|
@ -253,7 +253,9 @@ inline intptr_t* frame::interpreter_frame_locals() const {
|
||||
}
|
||||
|
||||
inline intptr_t* frame::interpreter_frame_last_sp() const {
|
||||
return (intptr_t*)at(interpreter_frame_last_sp_offset);
|
||||
intptr_t n = *addr_at(interpreter_frame_last_sp_offset);
|
||||
assert(n <= 0, "n: " INTPTR_FORMAT, n);
|
||||
return n != 0 ? &fp()[n] : nullptr;
|
||||
}
|
||||
|
||||
inline intptr_t* frame::interpreter_frame_bcp_addr() const {
|
||||
|
@ -491,7 +491,9 @@ void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
|
||||
// set sender sp
|
||||
mv(x19_sender_sp, sp);
|
||||
// record last_sp
|
||||
sd(esp, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
sub(t0, esp, fp);
|
||||
srai(t0, t0, Interpreter::logStackElementSize);
|
||||
sd(t0, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
}
|
||||
|
||||
// Jump to from_interpreted entry of a call unless single stepping is possible
|
||||
|
@ -426,7 +426,8 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
address entry = __ pc();
|
||||
|
||||
// Restore stack bottom in case i2c adjusted stack
|
||||
__ ld(esp, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ ld(t0, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ shadd(esp, t0, fp, t0, LogBytesPerWord);
|
||||
// and null it as marker that esp is now tos until next java call
|
||||
__ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ restore_bcp();
|
||||
@ -483,7 +484,8 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state,
|
||||
__ restore_sp_after_call(); // Restore SP to extended SP
|
||||
|
||||
// Restore expression stack pointer
|
||||
__ ld(esp, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ ld(t0, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ shadd(esp, t0, fp, t0, LogBytesPerWord);
|
||||
// null last_sp until next java call
|
||||
__ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
|
||||
@ -1604,7 +1606,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
/* notify_jvmdi */ false);
|
||||
|
||||
// Restore the last_sp and null it out
|
||||
__ ld(esp, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ ld(t0, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ shadd(esp, t0, fp, t0, LogBytesPerWord);
|
||||
__ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
|
||||
__ restore_bcp();
|
||||
|
@ -79,8 +79,8 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
|
||||
|
||||
intptr_t *sp, *fp; // sp is really our unextended_sp
|
||||
if (FKind::interpreted) {
|
||||
assert((intptr_t*)f.at(frame::interpreter_frame_last_sp_offset) == nullptr
|
||||
|| f.unextended_sp() == (intptr_t*)f.at(frame::interpreter_frame_last_sp_offset), "");
|
||||
assert((intptr_t*)f.at_relative_or_null(frame::interpreter_frame_last_sp_offset) == nullptr
|
||||
|| f.unextended_sp() == (intptr_t*)f.at_relative(frame::interpreter_frame_last_sp_offset), "");
|
||||
intptr_t locals_offset = *f.addr_at(frame::interpreter_frame_locals_offset);
|
||||
// If the caller.is_empty(), i.e. we're freezing into an empty chunk, then we set
|
||||
// the chunk's argsize in finalize_freeze and make room for it above the unextended_sp
|
||||
@ -120,7 +120,7 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
|
||||
|
||||
void FreezeBase::adjust_interpreted_frame_unextended_sp(frame& f) {
|
||||
assert((f.at(frame::interpreter_frame_last_sp_offset) != 0) || (f.unextended_sp() == f.sp()), "");
|
||||
intptr_t* real_unextended_sp = (intptr_t*)f.at(frame::interpreter_frame_last_sp_offset);
|
||||
intptr_t* real_unextended_sp = (intptr_t*)f.at_relative_or_null(frame::interpreter_frame_last_sp_offset);
|
||||
if (real_unextended_sp != nullptr) {
|
||||
f.set_unextended_sp(real_unextended_sp); // can be null at a safepoint
|
||||
}
|
||||
@ -141,8 +141,8 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
|
||||
|| (f.unextended_sp() == f.sp()), "");
|
||||
assert(f.fp() > (intptr_t*)f.at(frame::interpreter_frame_initial_sp_offset), "");
|
||||
|
||||
// at(frame::interpreter_frame_last_sp_offset) can be null at safepoint preempts
|
||||
*hf.addr_at(frame::interpreter_frame_last_sp_offset) = hf.unextended_sp() - hf.fp();
|
||||
// Make sure that last_sp is already relativized.
|
||||
assert((intptr_t*)hf.at_relative(frame::interpreter_frame_last_sp_offset) == hf.unextended_sp(), "");
|
||||
|
||||
// Make sure that locals is already relativized.
|
||||
assert((*hf.addr_at(frame::interpreter_frame_locals_offset) == frame::sender_sp_offset + f.interpreter_frame_method()->max_locals() - 1), "");
|
||||
@ -282,7 +282,9 @@ static inline void derelativize_one(intptr_t* const fp, int offset) {
|
||||
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
|
||||
intptr_t* vfp = f.fp();
|
||||
|
||||
derelativize_one(vfp, frame::interpreter_frame_last_sp_offset);
|
||||
// Make sure that last_sp is kept relativized.
|
||||
assert((intptr_t*)f.at_relative(frame::interpreter_frame_last_sp_offset) == f.unextended_sp(), "");
|
||||
|
||||
derelativize_one(vfp, frame::interpreter_frame_initial_sp_offset);
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,8 @@ inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f,
|
||||
assert(res == (intptr_t*)f.interpreter_frame_monitor_end() - expression_stack_sz, "");
|
||||
assert(res >= f.unextended_sp(),
|
||||
"res: " INTPTR_FORMAT " initial_sp: " INTPTR_FORMAT " last_sp: " INTPTR_FORMAT " unextended_sp: " INTPTR_FORMAT " expression_stack_size: %d",
|
||||
p2i(res), p2i(f.addr_at(frame::interpreter_frame_initial_sp_offset)), f.at(frame::interpreter_frame_last_sp_offset), p2i(f.unextended_sp()), expression_stack_sz);
|
||||
p2i(res), p2i(f.addr_at(frame::interpreter_frame_initial_sp_offset)), f.at_relative_or_null(frame::interpreter_frame_last_sp_offset),
|
||||
p2i(f.unextended_sp()), expression_stack_sz);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -352,7 +352,9 @@ void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
|
||||
|
||||
// Used by template based interpreter deoptimization
|
||||
void frame::interpreter_frame_set_last_sp(intptr_t* sp) {
|
||||
*((intptr_t**)addr_at(interpreter_frame_last_sp_offset)) = sp;
|
||||
assert(is_interpreted_frame(), "interpreted frame expected");
|
||||
// set relativized last_sp
|
||||
ptr_at_put(interpreter_frame_last_sp_offset, sp != nullptr ? (sp - fp()) : 0);
|
||||
}
|
||||
|
||||
frame frame::sender_for_entry_frame(RegisterMap* map) const {
|
||||
|
@ -250,7 +250,9 @@ inline intptr_t* frame::interpreter_frame_locals() const {
|
||||
}
|
||||
|
||||
inline intptr_t* frame::interpreter_frame_last_sp() const {
|
||||
return (intptr_t*)at(interpreter_frame_last_sp_offset);
|
||||
intptr_t n = *addr_at(interpreter_frame_last_sp_offset);
|
||||
assert(n <= 0, "n: " INTPTR_FORMAT, n);
|
||||
return n != 0 ? &fp()[n] : nullptr;
|
||||
}
|
||||
|
||||
inline intptr_t* frame::interpreter_frame_bcp_addr() const {
|
||||
|
@ -795,7 +795,10 @@ void InterpreterMacroAssembler::prepare_to_jump_from_interpreted() {
|
||||
// set sender sp
|
||||
lea(_bcp_register, Address(rsp, wordSize));
|
||||
// record last_sp
|
||||
movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), _bcp_register);
|
||||
mov(rcx, _bcp_register);
|
||||
subptr(rcx, rbp);
|
||||
sarptr(rcx, LogBytesPerWord);
|
||||
movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rcx);
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,7 +206,8 @@ address TemplateInterpreterGenerator::generate_return_entry_for(TosState state,
|
||||
#endif // _LP64
|
||||
|
||||
// Restore stack bottom in case i2c adjusted stack
|
||||
__ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ movptr(rcx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ lea(rsp, Address(rbp, rcx, Address::times_ptr));
|
||||
// and null it as marker that esp is now tos until next java call
|
||||
__ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
|
||||
|
||||
@ -1616,6 +1617,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
#ifndef _LP64
|
||||
__ mov(rax, rsp);
|
||||
__ movptr(rbx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ lea(rbx, Address(rbp, rbx, Address::times_ptr));
|
||||
__ get_thread(thread);
|
||||
// PC must point into interpreter here
|
||||
__ set_last_Java_frame(thread, noreg, rbp, __ pc(), noreg);
|
||||
@ -1624,6 +1626,7 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
#else
|
||||
__ mov(c_rarg1, rsp);
|
||||
__ movptr(c_rarg2, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ lea(c_rarg2, Address(rbp, c_rarg2, Address::times_ptr));
|
||||
// PC must point into interpreter here
|
||||
__ set_last_Java_frame(noreg, rbp, __ pc(), rscratch1);
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::popframe_move_outgoing_args), r15_thread, c_rarg1, c_rarg2);
|
||||
@ -1631,7 +1634,8 @@ void TemplateInterpreterGenerator::generate_throw_exception() {
|
||||
__ reset_last_Java_frame(thread, true);
|
||||
|
||||
// Restore the last_sp and null it out
|
||||
__ movptr(rsp, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ movptr(rcx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize));
|
||||
__ lea(rsp, Address(rbp, rcx, Address::times_ptr));
|
||||
__ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
|
||||
|
||||
__ restore_bcp();
|
||||
|
@ -1612,10 +1612,10 @@ void FrameValues::print_on(stackChunkOop chunk, outputStream* st) {
|
||||
while (!(start <= v0 && v0 <= end)) v0 = _values.at(++min_index).location;
|
||||
while (!(start <= v1 && v1 <= end)) v1 = _values.at(--max_index).location;
|
||||
|
||||
print_on(st, min_index, max_index, v0, v1, true /* on_heap */);
|
||||
print_on(st, min_index, max_index, v0, v1);
|
||||
}
|
||||
|
||||
void FrameValues::print_on(outputStream* st, int min_index, int max_index, intptr_t* v0, intptr_t* v1, bool on_heap) {
|
||||
void FrameValues::print_on(outputStream* st, int min_index, int max_index, intptr_t* v0, intptr_t* v1) {
|
||||
intptr_t* min = MIN2(v0, v1);
|
||||
intptr_t* max = MAX2(v0, v1);
|
||||
intptr_t* cur = max;
|
||||
@ -1630,8 +1630,7 @@ void FrameValues::print_on(outputStream* st, int min_index, int max_index, intpt
|
||||
const char* spacer = " " LP64_ONLY(" ");
|
||||
st->print_cr(" %s %s %s", spacer, spacer, fv.description);
|
||||
} else {
|
||||
if (on_heap
|
||||
&& *fv.location != 0 && *fv.location > -100 && *fv.location < 100
|
||||
if (*fv.location != 0 && *fv.location > -100 && *fv.location < 100
|
||||
#if !defined(PPC64)
|
||||
&& (strncmp(fv.description, "interpreter_frame_", 18) == 0 || strstr(fv.description, " method "))
|
||||
#else // !defined(PPC64)
|
||||
|
@ -249,6 +249,12 @@ class frame {
|
||||
// Interpreter frames in continuation stacks are on the heap, and internal addresses are relative to fp.
|
||||
intptr_t at_relative(int index) const { return (intptr_t)(fp() + fp()[index]); }
|
||||
|
||||
intptr_t at_relative_or_null(int index) const {
|
||||
return (fp()[index] != 0)
|
||||
? (intptr_t)(fp() + fp()[index])
|
||||
: 0;
|
||||
}
|
||||
|
||||
intptr_t at(int index) const {
|
||||
return _on_heap ? at_relative(index) : at_absolute(index);
|
||||
}
|
||||
@ -519,8 +525,7 @@ class FrameValues {
|
||||
return checked_cast<int>(a->location - b->location);
|
||||
}
|
||||
|
||||
void print_on(outputStream* out, int min_index, int max_index, intptr_t* v0, intptr_t* v1,
|
||||
bool on_heap = false);
|
||||
void print_on(outputStream* out, int min_index, int max_index, intptr_t* v0, intptr_t* v1);
|
||||
|
||||
public:
|
||||
// Used by frame functions to describe locations.
|
||||
|
Loading…
x
Reference in New Issue
Block a user