< 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 >