8315966: Relativize initial_sp in interpreter frames

Reviewed-by: fyang, mdoerr, pchilanomate
This commit is contained in:
Fredrik Bredberg 2023-09-27 13:15:07 +00:00 committed by Coleen Phillimore
parent b24ad7cf57
commit 347bd15e49
30 changed files with 154 additions and 118 deletions

View File

@ -129,20 +129,11 @@ void FreezeBase::adjust_interpreted_frame_unextended_sp(frame& f) {
}
}
static inline void relativize_one(intptr_t* const vfp, intptr_t* const hfp, int offset) {
assert(*(hfp + offset) == *(vfp + offset), "");
intptr_t* addr = hfp + offset;
intptr_t value = *(intptr_t**)addr - vfp;
*addr = value;
}
inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, const frame& hf) {
intptr_t* vfp = f.fp();
intptr_t* hfp = hf.fp();
assert(hfp == hf.unextended_sp() + (f.fp() - f.unextended_sp()), "");
assert(hf.fp() == hf.unextended_sp() + (f.fp() - f.unextended_sp()), "");
assert((f.at(frame::interpreter_frame_last_sp_offset) != 0)
|| (f.unextended_sp() == f.sp()), "");
assert(f.fp() > (intptr_t*)f.at(frame::interpreter_frame_initial_sp_offset), "");
assert(f.fp() > (intptr_t*)f.at_relative(frame::interpreter_frame_initial_sp_offset), "");
// on AARCH64, we may insert padding between the locals and the rest of the frame
// (see TemplateInterpreterGenerator::generate_normal_entry, and AbstractInterpreter::layout_activation)
@ -152,7 +143,8 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
// 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
// Make sure that monitor_block_top is already relativized.
assert(hf.at_absolute(frame::interpreter_frame_monitor_block_top_offset) <= frame::interpreter_frame_initial_sp_offset, "");
// extended_sp is already relativized by TemplateInterpreterGenerator::generate_normal_entry or
// AbstractInterpreter::layout_activation
@ -285,18 +277,12 @@ inline void ThawBase::patch_pd(frame& f, const frame& caller) {
patch_callee_link(caller, caller.fp());
}
static inline void derelativize_one(intptr_t* const fp, int offset) {
intptr_t* addr = fp + offset;
*addr = (intptr_t)(fp + *addr);
}
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
intptr_t* vfp = f.fp();
// 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);
// Make sure that monitor_block_top is still relativized.
assert(f.at_absolute(frame::interpreter_frame_monitor_block_top_offset) <= frame::interpreter_frame_initial_sp_offset, "");
// Make sure that extended_sp is kept relativized.
assert((intptr_t*)f.at_relative(frame::interpreter_frame_extended_sp_offset) < f.unextended_sp(), "");

View File

@ -134,7 +134,7 @@ inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f,
// interpreter_frame_last_sp_offset, points to unextended_sp includes arguments in the frame
// interpreter_frame_initial_sp_offset excludes expression stack slots
int expression_stack_sz = expression_stack_size(f, mask);
intptr_t* res = *(intptr_t**)f.addr_at(frame::interpreter_frame_initial_sp_offset) - expression_stack_sz;
intptr_t* res = (intptr_t*)f.at_relative(frame::interpreter_frame_initial_sp_offset) - expression_stack_sz;
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",

View File

@ -342,7 +342,7 @@ BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
}
BasicObjectLock* frame::interpreter_frame_monitor_end() const {
BasicObjectLock* result = (BasicObjectLock*) at(interpreter_frame_monitor_block_top_offset);
BasicObjectLock* result = (BasicObjectLock*) at_relative(interpreter_frame_monitor_block_top_offset);
// make sure the pointer points inside the frame
assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer");
assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer");
@ -350,7 +350,10 @@ BasicObjectLock* frame::interpreter_frame_monitor_end() const {
}
void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
*((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value;
assert(is_interpreted_frame(), "interpreted frame expected");
// set relativized monitor_block_top
ptr_at_put(interpreter_frame_monitor_block_top_offset, (intptr_t*)value - fp());
assert(at_absolute(interpreter_frame_monitor_block_top_offset) <= interpreter_frame_monitor_block_top_offset, "");
}
// Used by template based interpreter deoptimization

View File

@ -632,8 +632,10 @@ void InterpreterMacroAssembler::remove_activation(
bind(restart);
// We use c_rarg1 so that if we go slow path it will be the correct
// register for unlock_object to pass to VM directly
ldr(c_rarg1, monitor_block_top); // points to current entry, starting
// with top-most entry
ldr(c_rarg1, monitor_block_top); // derelativize pointer
lea(c_rarg1, Address(rfp, c_rarg1, Address::lsl(Interpreter::logStackElementSize)));
// c_rarg1 points to current entry, starting with top-most entry
lea(r19, monitor_block_bot); // points to word before bottom of
// monitor block
b(entry);

View File

@ -176,7 +176,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
void push(RegSet regs, Register stack) { ((MacroAssembler*)this)->push(regs, stack); }
void empty_expression_stack() {
ldr(esp, Address(rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
ldr(rscratch1, Address(rfp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
lea(esp, Address(rfp, rscratch1, Address::lsl(LogBytesPerWord)));
// null last_sp until next java call
str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
}

View File

@ -369,6 +369,7 @@ address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
__ ldr(rscratch1, Address(rfp,
frame::interpreter_frame_monitor_block_top_offset *
wordSize));
__ lea(rscratch1, Address(rfp, rscratch1, Address::lsl(Interpreter::logStackElementSize)));
__ mov(rscratch2, sp);
__ cmp(rscratch1, rscratch2); // maximal rsp for current rfp (stack
// grows negative)
@ -816,7 +817,10 @@ void TemplateInterpreterGenerator::lock_method() {
__ sub(rscratch1, sp, rfp);
__ asr(rscratch1, rscratch1, Interpreter::logStackElementSize);
__ str(rscratch1, Address(rfp, frame::interpreter_frame_extended_sp_offset * wordSize));
__ str(esp, monitor_block_top); // set new monitor block top
__ sub(rscratch1, esp, rfp);
__ asr(rscratch1, rscratch1, Interpreter::logStackElementSize);
__ str(rscratch1, monitor_block_top); // set new monitor block top
// store object
__ str(r0, Address(esp, BasicObjectLock::obj_offset()));
__ mov(c_rarg1, esp); // object address
@ -837,14 +841,16 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
if (native_call) {
__ sub(esp, sp, 14 * wordSize);
__ mov(rbcp, zr);
__ stp(esp, zr, Address(__ pre(sp, -14 * wordSize)));
__ mov(rscratch1, frame::interpreter_frame_initial_sp_offset);
__ stp(rscratch1, zr, Address(__ pre(sp, -14 * wordSize)));
// add 2 zero-initialized slots for native calls
__ stp(zr, zr, Address(sp, 12 * wordSize));
} else {
__ sub(esp, sp, 12 * wordSize);
__ ldr(rscratch1, Address(rmethod, Method::const_offset())); // get ConstMethod
__ add(rbcp, rscratch1, in_bytes(ConstMethod::codes_offset())); // get codebase
__ stp(esp, rbcp, Address(__ pre(sp, -12 * wordSize)));
__ mov(rscratch1, frame::interpreter_frame_initial_sp_offset);
__ stp(rscratch1, rbcp, Address(__ pre(sp, -12 * wordSize)));
}
if (ProfileInterpreter) {
@ -1258,6 +1264,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
const Address monitor_block_top(rfp,
frame::interpreter_frame_monitor_block_top_offset * wordSize);
__ ldr(rscratch1, monitor_block_top);
__ lea(rscratch1, Address(rfp, rscratch1, Address::lsl(Interpreter::logStackElementSize)));
__ cmp(esp, rscratch1);
__ br(Assembler::EQ, L);
__ stop("broken stack frame setup in interpreter 1");
@ -1710,6 +1717,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
const Address monitor_block_top (rfp,
frame::interpreter_frame_monitor_block_top_offset * wordSize);
__ ldr(rscratch1, monitor_block_top);
__ lea(rscratch1, Address(rfp, rscratch1, Address::lsl(Interpreter::logStackElementSize)));
__ cmp(esp, rscratch1);
__ br(Assembler::EQ, L);
__ stop("broken stack frame setup in interpreter 2");

View File

@ -3874,8 +3874,10 @@ void TemplateTable::monitorenter()
// find a free slot in the monitor block (result in c_rarg1)
{
Label entry, loop, exit;
__ ldr(c_rarg3, monitor_block_top); // points to current entry,
// starting with top-most entry
__ ldr(c_rarg3, monitor_block_top); // derelativize pointer
__ lea(c_rarg3, Address(rfp, c_rarg3, Address::lsl(Interpreter::logStackElementSize)));
// c_rarg3 points to current entry, starting with top-most entry
__ lea(c_rarg2, monitor_block_bot); // points to word before bottom
__ b(entry);
@ -3914,11 +3916,16 @@ void TemplateTable::monitorenter()
__ asr(rscratch1, rscratch1, Interpreter::logStackElementSize);
__ str(rscratch1, Address(rfp, frame::interpreter_frame_extended_sp_offset * wordSize));
__ ldr(c_rarg1, monitor_block_bot); // c_rarg1: old expression stack bottom
__ ldr(c_rarg1, monitor_block_bot); // derelativize pointer
__ lea(c_rarg1, Address(rfp, c_rarg1, Address::lsl(Interpreter::logStackElementSize)));
// c_rarg1 points to the old expression stack bottom
__ sub(esp, esp, entry_size); // move expression stack top
__ sub(c_rarg1, c_rarg1, entry_size); // move expression stack bottom
__ mov(c_rarg3, esp); // set start value for copy loop
__ str(c_rarg1, monitor_block_bot); // set new monitor block bottom
__ sub(rscratch1, c_rarg1, rfp); // relativize pointer
__ asr(rscratch1, rscratch1, Interpreter::logStackElementSize);
__ str(rscratch1, monitor_block_bot); // set new monitor block bottom
__ b(entry);
// 2. move expression stack contents
@ -3975,8 +3982,10 @@ void TemplateTable::monitorexit()
// find matching slot
{
Label entry, loop;
__ ldr(c_rarg1, monitor_block_top); // points to current entry,
// starting with top-most entry
__ ldr(c_rarg1, monitor_block_top); // derelativize pointer
__ lea(c_rarg1, Address(rfp, c_rarg1, Address::lsl(Interpreter::logStackElementSize)));
// c_rarg1 points to current entry, starting with top-most entry
__ lea(c_rarg2, monitor_block_bot); // points to word before bottom
// of monitor block
__ b(entry);

View File

@ -87,7 +87,9 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
// frame, because we freeze the padding (see recurse_freeze_interpreted_frame)
// in order to keep the same relativized locals pointer, we don't need to change it here.
relativize_one(vfp, hfp, ijava_idx(monitors));
// Make sure that monitors is already relativized.
assert(hf.at_absolute(ijava_idx(monitors)) <= -(frame::ijava_state_size / wordSize), "");
relativize_one(vfp, hfp, ijava_idx(esp));
// top_frame_sp is already relativized
@ -542,7 +544,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, ijava_idx(monitors));
// Make sure that monitors is still relativized.
assert(f.at_absolute(ijava_idx(monitors)) <= -(frame::ijava_state_size / wordSize), "");
derelativize_one(vfp, ijava_idx(esp));
// Keep top_frame_sp relativized.
}

View File

@ -456,7 +456,7 @@ frame::frame(void* sp, void* fp, void* pc) : frame((intptr_t*)sp, (address)pc) {
// Pointer beyond the "oldest/deepest" BasicObjectLock on stack.
BasicObjectLock* frame::interpreter_frame_monitor_end() const {
BasicObjectLock* result = (BasicObjectLock*) at(ijava_idx(monitors));
BasicObjectLock* result = (BasicObjectLock*) at_relative(ijava_idx(monitors));
// make sure the pointer points inside the frame
assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer");
assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer: result: " INTPTR_FORMAT " fp: " INTPTR_FORMAT, p2i(result), p2i(fp()));

View File

@ -228,7 +228,12 @@ inline intptr_t* frame::interpreter_frame_esp() const {
}
// Convenient setters
inline void frame::interpreter_frame_set_monitor_end(BasicObjectLock* end) { get_ijava_state()->monitors = (intptr_t) end;}
inline void frame::interpreter_frame_set_monitor_end(BasicObjectLock* end) {
assert(is_interpreted_frame(), "interpreted frame expected");
// set relativized monitors
get_ijava_state()->monitors = (intptr_t) ((intptr_t*)end - fp());
}
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; }

View File

@ -2217,7 +2217,9 @@ void InterpreterMacroAssembler::save_interpreter_state(Register scratch) {
ld(scratch, 0, R1_SP);
std(R15_esp, _ijava_state_neg(esp), scratch);
std(R14_bcp, _ijava_state_neg(bcp), scratch);
std(R26_monitor, _ijava_state_neg(monitors), scratch);
subf(R0, scratch, R26_monitor);
sradi(R0, R0, Interpreter::logStackElementSize);
std(R0, _ijava_state_neg(monitors), scratch);
if (ProfileInterpreter) { std(R28_mdx, _ijava_state_neg(mdx), scratch); }
// Other entries should be unchanged.
}
@ -2248,6 +2250,9 @@ void InterpreterMacroAssembler::restore_interpreter_state(Register scratch, bool
sldi(R18_locals, R18_locals, Interpreter::logStackElementSize);
add(R18_locals, R18_locals, scratch);
ld(R26_monitor, _ijava_state_neg(monitors), scratch);
// Derelativize monitors
sldi(R26_monitor, R26_monitor, Interpreter::logStackElementSize);
add(R26_monitor, R26_monitor, scratch);
}
#ifdef ASSERT
{

View File

@ -1055,7 +1055,8 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call, Regist
// Also initialize them for non-native calls for better tool support (even though
// you may not get the most recent version as described above).
__ li(R0, 0);
__ std(R26_monitor, _ijava_state_neg(monitors), R1_SP);
__ li(R12_scratch2, -(frame::ijava_state_size / wordSize));
__ std(R12_scratch2, _ijava_state_neg(monitors), R1_SP);
__ std(R14_bcp, _ijava_state_neg(bcp), R1_SP);
if (ProfileInterpreter) { __ std(R28_mdx, _ijava_state_neg(mdx), R1_SP); }
__ std(R15_esp, _ijava_state_neg(esp), R1_SP);
@ -1288,7 +1289,9 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// Update monitor in state.
__ ld(R11_scratch1, 0, R1_SP);
__ std(R26_monitor, _ijava_state_neg(monitors), R11_scratch1);
__ sub(R12_scratch2, R26_monitor, R11_scratch1);
__ sradi(R12_scratch2, R12_scratch2, Interpreter::logStackElementSize);
__ std(R12_scratch2, _ijava_state_neg(monitors), R11_scratch1);
}
// jvmti/jvmpi support

View File

@ -127,20 +127,11 @@ void FreezeBase::adjust_interpreted_frame_unextended_sp(frame& f) {
}
}
static inline void relativize_one(intptr_t* const vfp, intptr_t* const hfp, int offset) {
assert(*(hfp + offset) == *(vfp + offset), "");
intptr_t* addr = hfp + offset;
intptr_t value = *(intptr_t**)addr - vfp;
*addr = value;
}
inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, const frame& hf) {
intptr_t* vfp = f.fp();
intptr_t* hfp = hf.fp();
assert(hfp == hf.unextended_sp() + (f.fp() - f.unextended_sp()), "");
assert(hf.fp() == hf.unextended_sp() + (f.fp() - f.unextended_sp()), "");
assert((f.at(frame::interpreter_frame_last_sp_offset) != 0)
|| (f.unextended_sp() == f.sp()), "");
assert(f.fp() > (intptr_t*)f.at(frame::interpreter_frame_initial_sp_offset), "");
assert(f.fp() > (intptr_t*)f.at_relative(frame::interpreter_frame_initial_sp_offset), "");
// On RISCV, we may insert padding between the locals and the rest of the frame
// (see TemplateInterpreterGenerator::generate_normal_entry, and AbstractInterpreter::layout_activation)
@ -150,7 +141,8 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
// 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
// Make sure that monitor_block_top is already relativized.
assert(hf.at_absolute(frame::interpreter_frame_monitor_block_top_offset) <= frame::interpreter_frame_initial_sp_offset, "");
// extended_sp is already relativized by TemplateInterpreterGenerator::generate_normal_entry or
// AbstractInterpreter::layout_activation
@ -287,18 +279,12 @@ inline void ThawBase::patch_pd(frame& f, const frame& caller) {
patch_callee_link(caller, caller.fp());
}
static inline void derelativize_one(intptr_t* const fp, int offset) {
intptr_t* addr = fp + offset;
*addr = (intptr_t)(fp + *addr);
}
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
intptr_t* vfp = f.fp();
// 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);
// Make sure that monitor_block_top is still relativized.
assert(f.at_absolute(frame::interpreter_frame_monitor_block_top_offset) <= frame::interpreter_frame_initial_sp_offset, "");
// Make sure that extended_sp is kept relativized.
assert((intptr_t*)f.at_relative(frame::interpreter_frame_extended_sp_offset) < f.unextended_sp(), "");

View File

@ -121,7 +121,7 @@ inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f,
// interpreter_frame_last_sp_offset, points to unextended_sp includes arguments in the frame
// interpreter_frame_initial_sp_offset excludes expression stack slots
int expression_stack_sz = expression_stack_size(f, mask);
intptr_t* res = *(intptr_t**)f.addr_at(frame::interpreter_frame_initial_sp_offset) - expression_stack_sz;
intptr_t* res = (intptr_t*)f.at_relative(frame::interpreter_frame_initial_sp_offset) - expression_stack_sz;
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",

View File

@ -318,7 +318,7 @@ BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
}
BasicObjectLock* frame::interpreter_frame_monitor_end() const {
BasicObjectLock* result = (BasicObjectLock*) at(interpreter_frame_monitor_block_top_offset);
BasicObjectLock* result = (BasicObjectLock*) at_relative(interpreter_frame_monitor_block_top_offset);
// make sure the pointer points inside the frame
assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer");
assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer");
@ -326,7 +326,10 @@ BasicObjectLock* frame::interpreter_frame_monitor_end() const {
}
void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
*((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value;
assert(is_interpreted_frame(), "interpreted frame expected");
// set relativized monitor_block_top
ptr_at_put(interpreter_frame_monitor_block_top_offset, (intptr_t*)value - fp());
assert(at_absolute(interpreter_frame_monitor_block_top_offset) <= interpreter_frame_monitor_block_top_offset, "");
}
// Used by template based interpreter deoptimization

View File

@ -700,8 +700,10 @@ void InterpreterMacroAssembler::remove_activation(
bind(restart);
// We use c_rarg1 so that if we go slow path it will be the correct
// register for unlock_object to pass to VM directly
ld(c_rarg1, monitor_block_top); // points to current entry, starting
// with top-most entry
ld(c_rarg1, monitor_block_top); // derelativize pointer
shadd(c_rarg1, c_rarg1, fp, c_rarg1, LogBytesPerWord);
// c_rarg1 points to current entry, starting with top-most entry
la(x9, monitor_block_bot); // points to word before bottom of
// monitor block
@ -2008,6 +2010,7 @@ void InterpreterMacroAssembler::verify_frame_setup() {
Label L;
const Address monitor_block_top(fp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
ld(t0, monitor_block_top);
shadd(t0, t0, fp, t0, LogBytesPerWord);
beq(esp, t0, L);
stop("broken stack frame setup in interpreter");
bind(L);

View File

@ -165,7 +165,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
void push(TosState state); // transition state -> vtos
void empty_expression_stack() {
ld(esp, Address(fp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
ld(t0, Address(fp, frame::interpreter_frame_monitor_block_top_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));
}

View File

@ -332,6 +332,7 @@ address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
{
Label L;
__ ld(t0, Address(fp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
__ shadd(t0, t0, fp, t0, LogBytesPerWord);
// maximal sp for current fp (stack grows negative)
// check if frame is complete
__ bge(t0, sp, L);
@ -713,7 +714,9 @@ void TemplateInterpreterGenerator::lock_method() {
__ sub(t0, sp, fp);
__ srai(t0, t0, Interpreter::logStackElementSize);
__ sd(t0, Address(fp, frame::interpreter_frame_extended_sp_offset * wordSize));
__ sd(esp, monitor_block_top); // set new monitor block top
__ sub(t0, esp, fp);
__ srai(t0, t0, Interpreter::logStackElementSize);
__ sd(t0, monitor_block_top); // set new monitor block top
// store object
__ sd(x10, Address(esp, BasicObjectLock::obj_offset()));
__ mv(c_rarg1, esp); // object address
@ -745,7 +748,8 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
__ add(sp, sp, - 12 * wordSize);
}
__ sd(xbcp, Address(sp, wordSize));
__ sd(esp, Address(sp, 0));
__ mv(t0, frame::interpreter_frame_initial_sp_offset);
__ sd(t0, Address(sp, 0));
if (ProfileInterpreter) {
Label method_data_continue;

View File

@ -3809,8 +3809,10 @@ void TemplateTable::monitorenter() {
// find a free slot in the monitor block (result in c_rarg1)
{
Label entry, loop, exit, notUsed;
__ ld(c_rarg3, monitor_block_top); // points to current entry,
// starting with top-most entry
__ ld(c_rarg3, monitor_block_top); // derelativize pointer
__ shadd(c_rarg3, c_rarg3, fp, c_rarg3, LogBytesPerWord);
// Now c_rarg3 points to current entry, starting with top-most entry
__ la(c_rarg2, monitor_block_bot); // points to word before bottom
__ j(entry);
@ -3848,11 +3850,16 @@ void TemplateTable::monitorenter() {
__ srai(t0, t0, Interpreter::logStackElementSize);
__ sd(t0, Address(fp, frame::interpreter_frame_extended_sp_offset * wordSize));
__ ld(c_rarg1, monitor_block_bot); // c_rarg1: old expression stack bottom
__ ld(c_rarg1, monitor_block_bot); // derelativize pointer
__ shadd(c_rarg1, c_rarg1, fp, c_rarg1, LogBytesPerWord);
// Now c_rarg1 points to the old expression stack bottom
__ sub(esp, esp, entry_size); // move expression stack top
__ sub(c_rarg1, c_rarg1, entry_size); // move expression stack bottom
__ mv(c_rarg3, esp); // set start value for copy loop
__ sd(c_rarg1, monitor_block_bot); // set new monitor block bottom
__ sub(t0, c_rarg1, fp); // relativize pointer
__ srai(t0, t0, Interpreter::logStackElementSize);
__ sd(t0, monitor_block_bot); // set new monitor block bottom
__ j(entry);
// 2. move expression stack contents
@ -3906,8 +3913,10 @@ void TemplateTable::monitorexit() {
// find matching slot
{
Label entry, loop;
__ ld(c_rarg1, monitor_block_top); // points to current entry,
// starting with top-most entry
__ ld(c_rarg1, monitor_block_top); // derelativize pointer
__ shadd(c_rarg1, c_rarg1, fp, c_rarg1, LogBytesPerWord);
// Now c_rarg1 points to current entry, starting with top-most entry
__ la(c_rarg2, monitor_block_bot); // points to word before bottom
// of monitor block
__ j(entry);

View File

@ -126,20 +126,11 @@ void FreezeBase::adjust_interpreted_frame_unextended_sp(frame& f) {
}
}
static inline void relativize_one(intptr_t* const vfp, intptr_t* const hfp, int offset) {
assert(*(hfp + offset) == *(vfp + offset), "");
intptr_t* addr = hfp + offset;
intptr_t value = *(intptr_t**)addr - vfp;
*addr = value;
}
inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, const frame& hf) {
intptr_t* vfp = f.fp();
intptr_t* hfp = hf.fp();
assert(hfp == hf.unextended_sp() + (f.fp() - f.unextended_sp()), "");
assert(hf.fp() == hf.unextended_sp() + (f.fp() - f.unextended_sp()), "");
assert((f.at(frame::interpreter_frame_last_sp_offset) != 0)
|| (f.unextended_sp() == f.sp()), "");
assert(f.fp() > (intptr_t*)f.at(frame::interpreter_frame_initial_sp_offset), "");
assert(f.fp() > (intptr_t*)f.at_relative(frame::interpreter_frame_initial_sp_offset), "");
// Make sure that last_sp is already relativized.
assert((intptr_t*)hf.at_relative(frame::interpreter_frame_last_sp_offset) == hf.unextended_sp(), "");
@ -147,7 +138,8 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
// 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), "");
relativize_one(vfp, hfp, frame::interpreter_frame_initial_sp_offset); // == block_top == block_bottom
// Make sure that monitor_block_top is already relativized.
assert(hf.at_absolute(frame::interpreter_frame_monitor_block_top_offset) <= frame::interpreter_frame_initial_sp_offset, "");
assert((hf.fp() - hf.unextended_sp()) == (f.fp() - f.unextended_sp()), "");
assert(hf.unextended_sp() == (intptr_t*)hf.at(frame::interpreter_frame_last_sp_offset), "");
@ -274,18 +266,12 @@ inline void ThawBase::patch_pd(frame& f, const frame& caller) {
patch_callee_link(caller, caller.fp());
}
static inline void derelativize_one(intptr_t* const fp, int offset) {
intptr_t* addr = fp + offset;
*addr = (intptr_t)(fp + *addr);
}
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
intptr_t* vfp = f.fp();
// 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);
// Make sure that monitor_block_top is still relativized.
assert(f.at_absolute(frame::interpreter_frame_monitor_block_top_offset) <= frame::interpreter_frame_initial_sp_offset, "");
}
#endif // CPU_X86_CONTINUATIONFREEZE_THAW_X86_INLINE_HPP

View File

@ -121,7 +121,7 @@ inline intptr_t* ContinuationHelper::InterpretedFrame::frame_top(const frame& f,
// interpreter_frame_last_sp_offset, points to unextended_sp includes arguments in the frame
// interpreter_frame_initial_sp_offset excludes expression stack slots
int expression_stack_sz = expression_stack_size(f, mask);
intptr_t* res = *(intptr_t**)f.addr_at(frame::interpreter_frame_initial_sp_offset) - expression_stack_sz;
intptr_t* res = (intptr_t*)f.at_relative(frame::interpreter_frame_initial_sp_offset) - expression_stack_sz;
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",

View File

@ -339,7 +339,7 @@ BasicObjectLock* frame::interpreter_frame_monitor_begin() const {
}
BasicObjectLock* frame::interpreter_frame_monitor_end() const {
BasicObjectLock* result = (BasicObjectLock*) at(interpreter_frame_monitor_block_top_offset);
BasicObjectLock* result = (BasicObjectLock*) at_relative(interpreter_frame_monitor_block_top_offset);
// make sure the pointer points inside the frame
assert(sp() <= (intptr_t*) result, "monitor end should be above the stack pointer");
assert((intptr_t*) result < fp(), "monitor end should be strictly below the frame pointer: result: " INTPTR_FORMAT " fp: " INTPTR_FORMAT, p2i(result), p2i(fp()));
@ -347,7 +347,10 @@ BasicObjectLock* frame::interpreter_frame_monitor_end() const {
}
void frame::interpreter_frame_set_monitor_end(BasicObjectLock* value) {
*((BasicObjectLock**)addr_at(interpreter_frame_monitor_block_top_offset)) = value;
assert(is_interpreted_frame(), "interpreted frame expected");
// set relativized monitor_block_top
ptr_at_put(interpreter_frame_monitor_block_top_offset, (intptr_t*)value - fp());
assert(at_absolute(interpreter_frame_monitor_block_top_offset) <= interpreter_frame_monitor_block_top_offset, "");
}
// Used by template based interpreter deoptimization

View File

@ -1085,8 +1085,10 @@ void InterpreterMacroAssembler::remove_activation(
bind(restart);
// We use c_rarg1 so that if we go slow path it will be the correct
// register for unlock_object to pass to VM directly
movptr(rmon, monitor_block_top); // points to current entry, starting
// with top-most entry
movptr(rmon, monitor_block_top); // derelativize pointer
lea(rmon, Address(rbp, rmon, Address::times_ptr));
// c_rarg1 points to current entry, starting with top-most entry
lea(rbx, monitor_block_bot); // points to word before bottom of
// monitor block
jmp(entry);

View File

@ -177,7 +177,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
void push(TosState state); // transition state -> vtos
void empty_expression_stack() {
movptr(rsp, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
movptr(rcx, Address(rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize));
lea(rsp, Address(rbp, rcx, Address::times_ptr));
// null last_sp until next java call
movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
NOT_LP64(empty_FPU_stack());

View File

@ -86,9 +86,10 @@ address TemplateInterpreterGenerator::generate_StackOverflowError_handler() {
#ifdef ASSERT
{
Label L;
__ lea(rax, Address(rbp,
__ movptr(rax, Address(rbp,
frame::interpreter_frame_monitor_block_top_offset *
wordSize));
__ lea(rax, Address(rbp, rax, Address::times_ptr));
__ cmpptr(rax, rsp); // rax = maximal rsp for current rbp (stack
// grows negative)
__ jcc(Assembler::aboveEqual, L); // check if frame is complete
@ -608,7 +609,7 @@ void TemplateInterpreterGenerator::lock_method() {
// add space for monitor & lock
__ subptr(rsp, entry_size); // add space for a monitor entry
__ movptr(monitor_block_top, rsp); // set new monitor block top
__ subptr(monitor_block_top, entry_size / wordSize); // set new monitor block top
// store object
__ movptr(Address(rsp, BasicObjectLock::obj_offset()), rax);
const Register lockreg = NOT_LP64(rdx) LP64_ONLY(c_rarg1);
@ -664,8 +665,8 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
} else {
__ push(rbcp); // set bcp
}
__ push(0); // reserve word for pointer to expression stack bottom
__ movptr(Address(rsp, 0), rsp); // set expression stack bottom
// initialize relativized pointer to expression stack bottom
__ push(frame::interpreter_frame_initial_sp_offset);
}
// End of helpers
@ -904,6 +905,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
const Address monitor_block_top(rbp,
frame::interpreter_frame_monitor_block_top_offset * wordSize);
__ movptr(rax, monitor_block_top);
__ lea(rax, Address(rbp, rax, Address::times_ptr));
__ cmpptr(rax, rsp);
__ jcc(Assembler::equal, L);
__ stop("broken stack frame setup in interpreter 5");
@ -1458,6 +1460,7 @@ address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
const Address monitor_block_top (rbp,
frame::interpreter_frame_monitor_block_top_offset * wordSize);
__ movptr(rax, monitor_block_top);
__ lea(rax, Address(rbp, rax, Address::times_ptr));
__ cmpptr(rax, rsp);
__ jcc(Assembler::equal, L);
__ stop("broken stack frame setup in interpreter 6");

View File

@ -4358,8 +4358,10 @@ void TemplateTable::monitorenter() {
// find a free slot in the monitor block (result in rmon)
{
Label entry, loop, exit;
__ movptr(rtop, monitor_block_top); // points to current entry,
// starting with top-most entry
__ movptr(rtop, monitor_block_top); // derelativize pointer
__ lea(rtop, Address(rbp, rtop, Address::times_ptr));
// rtop points to current entry, starting with top-most entry
__ lea(rbot, monitor_block_bot); // points to word before bottom
// of monitor block
__ jmpb(entry);
@ -4391,10 +4393,11 @@ void TemplateTable::monitorenter() {
Label entry, loop;
// 1. compute new pointers // rsp: old expression stack top
__ movptr(rmon, monitor_block_bot); // rmon: old expression stack bottom
__ lea(rmon, Address(rbp, rmon, Address::times_ptr));
__ subptr(rsp, entry_size); // move expression stack top
__ subptr(rmon, entry_size); // move expression stack bottom
__ mov(rtop, rsp); // set start value for copy loop
__ movptr(monitor_block_bot, rmon); // set new monitor block bottom
__ subptr(monitor_block_bot, entry_size / wordSize); // set new monitor block bottom
__ jmp(entry);
// 2. move expression stack contents
__ bind(loop);
@ -4451,8 +4454,10 @@ void TemplateTable::monitorexit() {
// find matching slot
{
Label entry, loop;
__ movptr(rtop, monitor_block_top); // points to current entry,
// starting with top-most entry
__ movptr(rtop, monitor_block_top); // derelativize pointer
__ lea(rtop, Address(rbp, rtop, Address::times_ptr));
// rtop points to current entry, starting with top-most entry
__ lea(rbot, monitor_block_bot); // points to word before bottom
// of monitor block
__ jmpb(entry);

View File

@ -524,7 +524,8 @@ public class AARCH64Frame extends Frame {
}
public BasicObjectLock interpreterFrameMonitorEnd() {
Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0);
long n = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getCIntegerAt(0, VM.getVM().getAddressSize(), false);
Address result = getFP().addOffsetTo(n * VM.getVM().getAddressSize());
if (Assert.ASSERTS_ENABLED) {
// make sure the pointer points inside the frame
Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer");

View File

@ -445,7 +445,8 @@ public class PPC64Frame extends Frame {
}
public BasicObjectLock interpreterFrameMonitorEnd() {
Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITORS_OFFSET).getAddressAt(0);
long n = addressOfStackSlot(INTERPRETER_FRAME_MONITORS_OFFSET).getCIntegerAt(0, VM.getVM().getAddressSize(), false);
Address result = getFP().addOffsetTo(n * VM.getVM().getAddressSize());
if (Assert.ASSERTS_ENABLED) {
// make sure the pointer points inside the frame
Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer");

View File

@ -496,7 +496,8 @@ public class RISCV64Frame extends Frame {
}
public BasicObjectLock interpreterFrameMonitorEnd() {
Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0);
long n = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getCIntegerAt(0, VM.getVM().getAddressSize(), false);
Address result = getFP().addOffsetTo(n * VM.getVM().getAddressSize());
if (Assert.ASSERTS_ENABLED) {
// make sure the pointer points inside the frame
Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer");

View File

@ -512,7 +512,8 @@ public class X86Frame extends Frame {
}
public BasicObjectLock interpreterFrameMonitorEnd() {
Address result = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getAddressAt(0);
long n = addressOfStackSlot(INTERPRETER_FRAME_MONITOR_BLOCK_TOP_OFFSET).getCIntegerAt(0, VM.getVM().getAddressSize(), false);
Address result = getFP().addOffsetTo(n * VM.getVM().getAddressSize());
if (Assert.ASSERTS_ENABLED) {
// make sure the pointer points inside the frame
Assert.that(AddressOps.gt(getFP(), result), "result must < than frame pointer");