Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8272753: [lworld] "Invalid frame size" assert in frame::repair_sender_sp #536

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -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);
}
}