< prev index next >

src/hotspot/cpu/x86/frame_x86.cpp

Print this page

        

@@ -142,17 +142,20 @@
       sender_sp = _unextended_sp + _cb->frame_size();
       // Is sender_sp safe?
       if ((address)sender_sp >= thread->stack_base()) {
         return false;
       }
-      sender_unextended_sp = sender_sp;
       // On Intel the return_address is always the word on the stack
       sender_pc = (address) *(sender_sp-1);
       // Note: frame::sender_sp_offset is only valid for compiled frame
-      saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
-    }
+      intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset);
+      saved_fp = *saved_fp_addr;
 
+      // Repair the sender sp if this is a method with scalarized value type args
+      sender_sp = repair_sender_sp(sender_sp, saved_fp_addr);
+      sender_unextended_sp = sender_sp;
+    }
 
     // If the potential sender is the interpreter then we can do some more checking
     if (Interpreter::contains(sender_pc)) {
 
       // ebp is always saved in a recognizable place in any code we generate. However

@@ -452,19 +455,21 @@
   assert(map != NULL, "map must be set");
 
   // frame owned by optimizing compiler
   assert(_cb->frame_size() >= 0, "must have non-zero frame size");
   intptr_t* sender_sp = unextended_sp() + _cb->frame_size();
-  intptr_t* unextended_sp = sender_sp;
 
   // On Intel the return_address is always the word on the stack
   address sender_pc = (address) *(sender_sp-1);
 
   // This is the saved value of EBP which may or may not really be an FP.
   // It is only an FP if the sender is an interpreter frame (or C1?).
   intptr_t** saved_fp_addr = (intptr_t**) (sender_sp - frame::sender_sp_offset);
 
+  // Repair the sender sp if this is a method with scalarized value type args
+  sender_sp = repair_sender_sp(sender_sp, saved_fp_addr);
+
   if (map->update_map()) {
     // Tell GC to use argument oopmaps for some runtime stubs that need it.
     // For C1, the runtime stub might not have oop maps, so set this flag
     // outside of update_register_map.
     map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));

@@ -477,11 +482,11 @@
     // since if our caller was compiled code there could be live jvm state in it.
     update_map_with_saved_link(map, saved_fp_addr);
   }
 
   assert(sender_sp != sp(), "must have changed");
-  return frame(sender_sp, unextended_sp, *saved_fp_addr, sender_pc);
+  return frame(sender_sp, sender_sp, *saved_fp_addr, sender_pc);
 }
 
 
 //------------------------------------------------------------------------------
 // frame::sender

@@ -583,10 +588,11 @@
     tos_addr = (intptr_t*)interpreter_frame_tos_address();
   }
 
   switch (type) {
     case T_OBJECT  :
+    case T_VALUETYPE:
     case T_ARRAY   : {
       oop obj;
       if (method->is_native()) {
         obj = cast_to_oop(at(interpreter_frame_oop_temp_offset));
       } else {

@@ -684,10 +690,26 @@
 }
 
 void frame::pd_ps() {}
 #endif
 
+// Check for a method with scalarized value type arguments that needs
+// a stack repair and return the repaired sender stack pointer.
+intptr_t* frame::repair_sender_sp(intptr_t* sender_sp, intptr_t** saved_fp_addr) const {
+  CompiledMethod* cm = _cb->as_compiled_method_or_null();
+  if (cm != NULL && cm->method()->needs_stack_repair()) {
+    // The stack increment resides just below the saved rbp on the stack
+    // and does not account for the return address.
+    intptr_t* sp_inc_addr = (intptr_t*) (saved_fp_addr - 1);
+    int sp_inc = (*sp_inc_addr) / wordSize;
+    int real_frame_size = sp_inc + 1; // Add size of return address
+    assert(real_frame_size >= _cb->frame_size(), "invalid frame size");
+    sender_sp = unextended_sp() + real_frame_size;
+  }
+  return sender_sp;
+}
+
 void JavaFrameAnchor::make_walkable(JavaThread* thread) {
   // last frame set?
   if (last_Java_sp() == NULL) return;
   // already walkable?
   if (walkable()) return;
< prev index next >