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

8244092: [lworld] TestC2CCalls segfaults in frame::sender_for_compiled_frame with ZGC #31

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 31 additions & 44 deletions src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp
Expand Up @@ -317,6 +317,26 @@ void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
assert(UseCompressedClassPointers || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
}

void C1_MacroAssembler::build_frame_helper(int frame_size_in_bytes, int sp_inc, bool needs_stack_repair) {
push(rbp);
if (PreserveFramePointer) {
mov(rbp, rsp);
}
#if !defined(_LP64) && defined(TIERED)
if (UseSSE < 2 ) {
// c2 leaves fpu stack dirty. Clean it on entry
empty_FPU_stack();
}
#endif // !_LP64 && TIERED
decrement(rsp, frame_size_in_bytes);

if (needs_stack_repair) {
// Save stack increment (also account for fixed framesize and rbp)
assert((sp_inc & (StackAlignmentInBytes-1)) == 0, "stack increment not aligned");
int real_frame_size = sp_inc + frame_size_in_bytes + wordSize;
movptr(Address(rsp, frame_size_in_bytes - wordSize), real_frame_size);
}
}

void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes, int sp_offset_for_orig_pc, bool needs_stack_repair, bool has_scalarized_args, Label* verified_value_entry_label) {
if (has_scalarized_args) {
Expand All @@ -333,26 +353,14 @@ void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_by
// between the two compilers.
assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
generate_stack_overflow_check(bang_size_in_bytes);
push(rbp);
if (PreserveFramePointer) {
mov(rbp, rsp);
}
#if !defined(_LP64) && defined(TIERED)
if (UseSSE < 2 ) {
// c2 leaves fpu stack dirty. Clean it on entry
empty_FPU_stack();
}
#endif // !_LP64 && TIERED
decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
if (needs_stack_repair) {
// Save stack increment (also account for rbp)
int real_frame_size = frame_size_in_bytes + wordSize;
movptr(Address(rsp, frame_size_in_bytes - wordSize), real_frame_size);
if (verified_value_entry_label != NULL) {
bind(*verified_value_entry_label);
}
}

build_frame_helper(frame_size_in_bytes, 0, needs_stack_repair);

if (needs_stack_repair && verified_value_entry_label != NULL) {
// Jump here from the scalarized entry points that require additional stack space
// for packing scalarized arguments and therefore already created the frame.
bind(*verified_value_entry_label);
}
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
bs->nmethod_entry_barrier(this);
}
Expand Down Expand Up @@ -404,18 +412,7 @@ int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature *ces, int f
}

// Create a temp frame so we can call into the runtime. It must be properly set up to accommodate GC.
push(rbp);
if (PreserveFramePointer) {
mov(rbp, rsp);
}
subptr(rsp, frame_size_in_bytes);

if (ces->c1_needs_stack_repair()) {
// Save stack increment (also account for fixed framesize and rbp)
assert((sp_inc & (StackAlignmentInBytes-1)) == 0, "stack increment not aligned");
int real_frame_size = sp_inc + frame_size_in_bytes + wordSize;
movptr(Address(rsp, frame_size_in_bytes - wordSize), real_frame_size);
}
build_frame_helper(frame_size_in_bytes, sp_inc, ces->c1_needs_stack_repair());

// Initialize orig_pc to detect deoptimization during buffering in below runtime call
movptr(Address(rsp, sp_offset_for_orig_pc), 0);
Expand All @@ -438,19 +435,9 @@ int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature *ces, int f
args_passed, args_on_stack, regs, sp_inc); // to

if (ces->c1_needs_stack_repair()) {
// Skip over the stack banging and frame setup code in the
// verified_value_entry (which has a different real_frame_size).
push(rbp);
if (PreserveFramePointer) {
mov(rbp, rsp);
}
#if !defined(_LP64) && defined(TIERED)
// c2 leaves fpu stack dirty. Clean it on entry
if (UseSSE < 2 ) {
empty_FPU_stack();
}
#endif // TIERED
decrement(rsp, frame_size_in_bytes);
// Create the real frame. Below jump will then skip over the stack banging and frame
// setup code in the verified_value_entry (which has a different real_frame_size).
build_frame_helper(frame_size_in_bytes, sp_inc, true);
}

jmp(verified_value_entry_label);
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/cpu/x86/frame_x86.cpp
Expand Up @@ -715,7 +715,7 @@ intptr_t* frame::repair_sender_sp(intptr_t* sender_sp, intptr_t** saved_fp_addr)
// and does not account for the return address.
intptr_t* real_frame_size_addr = (intptr_t*) (saved_fp_addr - 1);
int real_frame_size = ((*real_frame_size_addr) + wordSize) / wordSize;
assert(real_frame_size >= _cb->frame_size(), "invalid frame size");
assert(real_frame_size >= _cb->frame_size() && real_frame_size <= 1000000, "invalid frame size");
sender_sp = unextended_sp() + real_frame_size;
}
return sender_sp;
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/c1/c1_MacroAssembler.hpp
Expand Up @@ -33,6 +33,7 @@ class CompiledEntrySignature;
class C1_MacroAssembler: public MacroAssembler {
private:
int scalarized_entry(const CompiledEntrySignature *ces, int frame_size_in_bytes, int bang_size_in_bytes, int sp_offset_for_orig_pc, Label& verified_value_entry_label, bool is_value_ro_entry);
void build_frame_helper(int frame_size_in_bytes, int sp_inc, bool needs_stack_repair);
public:
// creation
C1_MacroAssembler(CodeBuffer* code) : MacroAssembler(code) { pd_init(); }
Expand Down