Skip to content
Permalink
Browse files
8272753: [lworld] "Invalid frame size" assert in frame::repair_sender_sp
  • Loading branch information
TobiHartmann committed Aug 20, 2021
1 parent 55f8d9e commit aaa7401c49e87f9790c2ebf21e72198b2dafcd9d
@@ -484,8 +484,7 @@ int LIR_Assembler::emit_unwind_handler() {
}

// remove the activation and dispatch to the unwind handler
int initial_framesize = initial_frame_size_in_bytes();
__ remove_frame(initial_framesize, needs_stack_repair(), initial_framesize - wordSize);
__ remove_frame(initial_frame_size_in_bytes(), needs_stack_repair());
__ jump(RuntimeAddress(Runtime1::entry_for(Runtime1::unwind_exception_id)));

// Emit the slow path assembly
@@ -547,8 +546,7 @@ void LIR_Assembler::return_op(LIR_Opr result, C1SafepointPollStub* code_stub) {
}

// Pop the stack before the safepoint code
int initial_framesize = initial_frame_size_in_bytes();
__ remove_frame(initial_framesize, needs_stack_repair(), initial_framesize - wordSize);
__ remove_frame(initial_frame_size_in_bytes(), needs_stack_repair());

if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
__ reserved_stack_check();
@@ -5355,9 +5355,9 @@ void MacroAssembler::verified_entry(Compile* C, int sp_inc) {
}

if (C->needs_stack_repair()) {
// Save stack increment (also account for fixed framesize and rbp)
// Save stack increment just below the saved rbp (also account for fixed framesize and rbp)
assert((sp_inc & (StackAlignmentInBytes-1)) == 0, "stack increment not aligned");
movptr(Address(rsp, C->output()->sp_inc_offset()), sp_inc + framesize + wordSize);
movptr(Address(rsp, framesize - wordSize), sp_inc + framesize + wordSize);
}

if (VerifyStackAtCalls) { // Majik cookie to verify stack depth
@@ -5766,11 +5766,12 @@ VMReg MacroAssembler::spill_reg_for(VMReg reg) {
return reg->is_XMMRegister() ? xmm8->as_VMReg() : r14->as_VMReg();
}

void MacroAssembler::remove_frame(int initial_framesize, bool needs_stack_repair, int sp_inc_offset) {
void MacroAssembler::remove_frame(int initial_framesize, bool needs_stack_repair) {
assert((initial_framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
if (needs_stack_repair) {
movq(rbp, Address(rsp, initial_framesize));
addq(rsp, Address(rsp, sp_inc_offset));
// The stack increment resides just below the saved rbp
addq(rsp, Address(rsp, initial_framesize - wordSize));
} else {
if (initial_framesize > 0) {
addq(rsp, initial_framesize);
@@ -1772,7 +1772,7 @@ class MacroAssembler: public Assembler {
VMRegPair* from, int from_count, int& from_index, VMReg to,
RegState reg_state[], Register val_array);
int extend_stack_for_inline_args(int args_on_stack);
void remove_frame(int initial_framesize, bool needs_stack_repair, int sp_inc_offset);
void remove_frame(int initial_framesize, bool needs_stack_repair);
VMReg spill_reg_for(VMReg reg);

// clear memory of size 'cnt' qwords, starting at 'base';
@@ -975,7 +975,7 @@ void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const

// Subtract two words to account for return address and rbp
int initial_framesize = C->output()->frame_size_in_bytes() - 2*wordSize;
__ remove_frame(initial_framesize, C->needs_stack_repair(), C->output()->sp_inc_offset());
__ remove_frame(initial_framesize, C->needs_stack_repair());

if (StackReservedPages > 0 && C->has_reserved_stack_access()) {
__ reserved_stack_check();
@@ -1130,4 +1130,63 @@ public void test50_verifier() {
test50(true);
test50(false);
}

// Test stack repair with stack slots reserved for monitors
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
private static final Object lock3 = new Object();

@DontInline
static void test51_callee() { }

@Test
public void test51(MyValue1 val) {
synchronized (lock1) {
test51_callee();
}
}

@Run(test = "test51")
public void test51_verifier() {
MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
test51(vt);
}

@DontInline
static void test52_callee() { }

@Test
public void test52(MyValue1 val) {
synchronized (lock1) {
synchronized (lock2) {
test52_callee();
}
}
}

@Run(test = "test52")
public void test52_verifier() {
MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
test52(vt);
}

@DontInline
static void test53_callee() { }

@Test
public void test53(MyValue1 val) {
synchronized (lock1) {
synchronized (lock2) {
synchronized (lock3) {
test53_callee();
}
}
}
}

@Run(test = "test53")
public void test53_verifier() {
MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
test53(vt);
}
}

0 comments on commit aaa7401

Please sign in to comment.