diff --git a/src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp index 4e4aa95e171..23a5ad71025 100644 --- a/src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp +++ b/src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp @@ -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); } diff --git a/src/hotspot/cpu/aarch64/continuationHelper_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/continuationHelper_aarch64.inline.hpp index 7d673eb8d0d..38005383248 100644 --- a/src/hotspot/cpu/aarch64/continuationHelper_aarch64.inline.hpp +++ b/src/hotspot/cpu/aarch64/continuationHelper_aarch64.inline.hpp @@ -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; } diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.cpp b/src/hotspot/cpu/aarch64/frame_aarch64.cpp index 2357721ed3d..4ceae831e66 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp @@ -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 diff --git a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp index 5fc5fe9248e..c0ae3cdf2ac 100644 --- a/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp +++ b/src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp @@ -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 { diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index a86cc40ab50..823e481178e 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -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 diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index 0f03c5f9b6f..ee69114ea26 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -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(); diff --git a/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp b/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp index c72a4c8a54d..888b0870fe6 100644 --- a/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp @@ -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) { diff --git a/src/hotspot/cpu/ppc/continuationHelper_ppc.inline.hpp b/src/hotspot/cpu/ppc/continuationHelper_ppc.inline.hpp index 3f4ddd64723..528f1f8ad96 100644 --- a/src/hotspot/cpu/ppc/continuationHelper_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/continuationHelper_ppc.inline.hpp @@ -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), ""); diff --git a/src/hotspot/cpu/ppc/frame_ppc.inline.hpp b/src/hotspot/cpu/ppc/frame_ppc.inline.hpp index c59aed8d77b..bad713fac84 100644 --- a/src/hotspot/cpu/ppc/frame_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/frame_ppc.inline.hpp @@ -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 { diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp index 2873fc2eca0..4dd289c74be 100644 --- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp +++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp @@ -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). diff --git a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp index 50d43a46d40..e3a8b3fbd94 100644 --- a/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp @@ -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. diff --git a/src/hotspot/cpu/riscv/continuationFreezeThaw_riscv.inline.hpp b/src/hotspot/cpu/riscv/continuationFreezeThaw_riscv.inline.hpp index 5bfa1a8756c..c581871fd8e 100644 --- a/src/hotspot/cpu/riscv/continuationFreezeThaw_riscv.inline.hpp +++ b/src/hotspot/cpu/riscv/continuationFreezeThaw_riscv.inline.hpp @@ -82,7 +82,7 @@ template 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 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); } diff --git a/src/hotspot/cpu/riscv/continuationHelper_riscv.inline.hpp b/src/hotspot/cpu/riscv/continuationHelper_riscv.inline.hpp index 58ca64f23e7..4e96a8231b1 100644 --- a/src/hotspot/cpu/riscv/continuationHelper_riscv.inline.hpp +++ b/src/hotspot/cpu/riscv/continuationHelper_riscv.inline.hpp @@ -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; } diff --git a/src/hotspot/cpu/riscv/frame_riscv.cpp b/src/hotspot/cpu/riscv/frame_riscv.cpp index f1518724608..e91b722bd02 100644 --- a/src/hotspot/cpu/riscv/frame_riscv.cpp +++ b/src/hotspot/cpu/riscv/frame_riscv.cpp @@ -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) { diff --git a/src/hotspot/cpu/riscv/frame_riscv.inline.hpp b/src/hotspot/cpu/riscv/frame_riscv.inline.hpp index 40455805984..dfec3880192 100644 --- a/src/hotspot/cpu/riscv/frame_riscv.inline.hpp +++ b/src/hotspot/cpu/riscv/frame_riscv.inline.hpp @@ -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 { diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index b8e155ccbba..96bbd6a3f30 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -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 diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index aeb9d58f670..ef6675eeebd 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -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(); diff --git a/src/hotspot/cpu/x86/continuationFreezeThaw_x86.inline.hpp b/src/hotspot/cpu/x86/continuationFreezeThaw_x86.inline.hpp index 08b1b285651..8630a4670db 100644 --- a/src/hotspot/cpu/x86/continuationFreezeThaw_x86.inline.hpp +++ b/src/hotspot/cpu/x86/continuationFreezeThaw_x86.inline.hpp @@ -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); } diff --git a/src/hotspot/cpu/x86/continuationHelper_x86.inline.hpp b/src/hotspot/cpu/x86/continuationHelper_x86.inline.hpp index 0b226b4b581..55794f9ac7e 100644 --- a/src/hotspot/cpu/x86/continuationHelper_x86.inline.hpp +++ b/src/hotspot/cpu/x86/continuationHelper_x86.inline.hpp @@ -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; } diff --git a/src/hotspot/cpu/x86/frame_x86.cpp b/src/hotspot/cpu/x86/frame_x86.cpp index 7e4b24e097d..0fc674ec69b 100644 --- a/src/hotspot/cpu/x86/frame_x86.cpp +++ b/src/hotspot/cpu/x86/frame_x86.cpp @@ -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 { diff --git a/src/hotspot/cpu/x86/frame_x86.inline.hpp b/src/hotspot/cpu/x86/frame_x86.inline.hpp index d7862afc292..67e5a1e0c43 100644 --- a/src/hotspot/cpu/x86/frame_x86.inline.hpp +++ b/src/hotspot/cpu/x86/frame_x86.inline.hpp @@ -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 { diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp index caa07857f03..e5b5aeebeca 100644 --- a/src/hotspot/cpu/x86/interp_masm_x86.cpp +++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp @@ -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); } diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp index 6bf129a2b34..ed905b1fd99 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp @@ -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(); diff --git a/src/hotspot/share/runtime/frame.cpp b/src/hotspot/share/runtime/frame.cpp index c0d6238f053..f4893bae5db 100644 --- a/src/hotspot/share/runtime/frame.cpp +++ b/src/hotspot/share/runtime/frame.cpp @@ -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) diff --git a/src/hotspot/share/runtime/frame.hpp b/src/hotspot/share/runtime/frame.hpp index fcfb51c008b..60869dfd09d 100644 --- a/src/hotspot/share/runtime/frame.hpp +++ b/src/hotspot/share/runtime/frame.hpp @@ -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(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.