--- old/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp 2019-07-02 19:11:30.920770537 -0700 +++ new/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp 2019-07-02 19:11:30.600759026 -0700 @@ -342,9 +342,10 @@ #endif // TIERED decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0 if (needs_stack_repair) { - movptr(Address(rsp, frame_size_in_bytes - wordSize), frame_size_in_bytes + int real_frame_size = frame_size_in_bytes + wordSize // skip over pushed rbp - + wordSize); // skip over RA pushed by caller + + wordSize; // skip over RA pushed by caller + movptr(Address(rsp, frame_size_in_bytes - wordSize), real_frame_size); if (verified_value_entry_label != NULL) { bind(*verified_value_entry_label); } @@ -398,12 +399,45 @@ if (C1Breakpoint)int3(); verify_FPU(0, "method_entry"); - // FIXME -- call runtime only if we cannot in-line allocate all the incoming value args. - push(rbp); // Create a temp frame so we can call into runtime // FIXME: need to be able to handle GC during the call + assert(ValueTypePassFieldsAsArgs, "sanity"); + GrowableArray* sig = &ces->sig(); + GrowableArray* sig_cc = is_value_ro_entry ? &ces->sig_cc_ro() : &ces->sig_cc(); + VMRegPair* regs = ces->regs(); + VMRegPair* regs_cc = is_value_ro_entry ? ces->regs_cc_ro() : ces->regs_cc(); + int args_on_stack = ces->args_on_stack(); + int args_on_stack_cc = is_value_ro_entry ? ces->args_on_stack_cc_ro() : ces->args_on_stack_cc(); + + assert(sig->length() <= sig_cc->length(), "Zero-sized value class not allowed!"); + BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sig_cc->length()); + int args_passed = sig->length(); + int args_passed_cc = SigEntry::fill_sig_bt(sig_cc, sig_bt); + + int extra_stack_offset = wordSize; // tos is return address. + + // Create a temp frame so we can call into runtime. It must be properly set up to accomodate GC. + int sp_inc = (args_on_stack - args_on_stack_cc) * VMRegImpl::stack_slot_size; + if (sp_inc > 0) { + pop(r13); + sp_inc = align_up(sp_inc, StackAlignmentInBytes); + subptr(rsp, sp_inc); + push(r13); + } else { + sp_inc = 0; + } + push(rbp); if (PreserveFramePointer) { mov(rbp, rsp); } subptr(rsp, frame_size_in_bytes); + if (sp_inc > 0) { + int real_frame_size = frame_size_in_bytes + + + wordSize // pushed rbp + + wordSize // returned address pushed by the stack extension code + + sp_inc; // stack extension + movptr(Address(rsp, frame_size_in_bytes - wordSize), real_frame_size); + } + + // FIXME -- call runtime only if we cannot in-line allocate all the incoming value args. movptr(rbx, (intptr_t)(ces->method())); if (is_value_ro_entry) { call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_value_args_no_receiver_id))); @@ -412,29 +446,18 @@ } int rt_call_offset = offset(); + // Remove the temp frame addptr(rsp, frame_size_in_bytes); pop(rbp); - assert(ValueTypePassFieldsAsArgs, "sanity"); - - GrowableArray* sig = &ces->sig(); - GrowableArray* sig_cc = is_value_ro_entry ? &ces->sig_cc_ro() : &ces->sig_cc(); - VMRegPair* regs = ces->regs(); - VMRegPair* regs_cc = is_value_ro_entry ? ces->regs_cc_ro() : ces->regs_cc(); - int args_on_stack = ces->args_on_stack(); - int args_on_stack_cc = is_value_ro_entry ? ces->args_on_stack_cc_ro() : ces->args_on_stack_cc(); - - assert(sig->length() <= sig_cc->length(), "Zero-sized value class not allowed!"); - BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sig_cc->length()); - int args_passed = sig->length(); - int args_passed_cc = SigEntry::fill_sig_bt(sig_cc, sig_bt); - - int extra_stack_offset = wordSize; // tos is return address. - int sp_inc = shuffle_value_args(true, is_value_ro_entry, extra_stack_offset, sig_bt, sig_cc, - args_passed_cc, args_on_stack_cc, regs_cc, // from - args_passed, args_on_stack, regs); // to + int n = shuffle_value_args(true, is_value_ro_entry, extra_stack_offset, sig_bt, sig_cc, + args_passed_cc, args_on_stack_cc, regs_cc, // from + args_passed, args_on_stack, regs); // to + assert(sp_inc == n, "must be"); if (sp_inc != 0) { + // Do the stack banging here, and skip over the stack repair code in the + // verified_value_entry (which has a different real_frame_size). assert(sp_inc > 0, "stack should not shrink"); generate_stack_overflow_check(bang_size_in_bytes); push(rbp); @@ -448,10 +471,6 @@ } #endif // TIERED decrement(rsp, frame_size_in_bytes); - movptr(Address(rsp, frame_size_in_bytes - wordSize), frame_size_in_bytes + - + wordSize // pushed rbp - + wordSize // returned address pushed by the stack extension code - + sp_inc); // stack extension } jmp(verified_value_entry_label);