Skip to content
Permalink
Browse files
8244092: [lworld] TestC2CCalls segfaults in frame::sender_for_compile…
…d_frame with ZGC
  • Loading branch information
TobiHartmann committed Apr 30, 2020
1 parent 21a4dae commit 750279778cd0d81dfb022f9c5d34a2a5a21bba0e
Showing with 33 additions and 45 deletions.
  1. +31 −44 src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp
  2. +1 −1 src/hotspot/cpu/x86/frame_x86.cpp
  3. +1 −0 src/hotspot/share/c1/c1_MacroAssembler.hpp
@@ -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) {
@@ -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);
}
@@ -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);
@@ -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);
@@ -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;
@@ -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(); }

0 comments on commit 7502797

Please sign in to comment.