< prev index next >
src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp
Print this page
@@ -340,13 +340,14 @@
empty_FPU_stack();
}
#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);
}
}
@@ -396,47 +397,69 @@
fat_nop();
}
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<SigEntry>* sig = &ces->sig();
+ GrowableArray<SigEntry>* 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)));
} else {
call(RuntimeAddress(Runtime1::entry_for(Runtime1::buffer_value_args_id)));
}
int rt_call_offset = offset();
+ // Remove the temp frame
addptr(rsp, frame_size_in_bytes);
pop(rbp);
- assert(ValueTypePassFieldsAsArgs, "sanity");
-
- GrowableArray<SigEntry>* sig = &ces->sig();
- GrowableArray<SigEntry>* 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,
+ 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);
if (PreserveFramePointer) {
mov(rbp, rsp);
@@ -446,14 +469,10 @@
if (UseSSE < 2 ) {
empty_FPU_stack();
}
#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);
return rt_call_offset;
}
< prev index next >