hotspot/src/share/vm/runtime/deoptimization.cpp
changeset 9437 9981851b4b8c
parent 8657 5bb183666ecd
child 9446 748a37b25d10
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Mon May 02 10:51:36 2011 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Mon May 02 18:53:37 2011 -0700
@@ -189,6 +189,10 @@
   assert(thread->deopt_nmethod() == NULL, "Pending deopt!");
   thread->set_deopt_nmethod(deoptee.cb()->as_nmethod_or_null());
 
+  if (VerifyStack) {
+    thread->validate_frame_layout();
+  }
+
   // Create a growable array of VFrames where each VFrame represents an inlined
   // Java frame.  This storage is allocated with the usual system arena.
   assert(deoptee.is_compiled_frame(), "Wrong frame type");
@@ -421,6 +425,21 @@
   frame deopt_sender = stub_frame.sender(&dummy_map); // First is the deoptee frame
   deopt_sender = deopt_sender.sender(&dummy_map);     // Now deoptee caller
 
+  // It's possible that the number of paramters at the call site is
+  // different than number of arguments in the callee when method
+  // handles are used.  If the caller is interpreted get the real
+  // value so that the proper amount of space can be added to it's
+  // frame.
+  int sender_callee_parameters = callee_parameters;
+  if (deopt_sender.is_interpreted_frame()) {
+    methodHandle method = deopt_sender.interpreter_frame_method();
+    Bytecode_invoke cur = Bytecode_invoke_check(method,
+                                                deopt_sender.interpreter_frame_bci());
+    Symbol* signature = method->constants()->signature_ref_at(cur.index());
+    ArgumentSizeComputer asc(signature);
+    sender_callee_parameters = asc.size() + cur.has_receiver() ? 1 : 0;
+  }
+
   // Compute the amount the oldest interpreter frame will have to adjust
   // its caller's stack by. If the caller is a compiled frame then
   // we pretend that the callee has no parameters so that the
@@ -435,14 +454,13 @@
 
   if (deopt_sender.is_compiled_frame()) {
     caller_adjustment = last_frame_adjust(0, callee_locals);
-  } else if (callee_locals > callee_parameters) {
+  } else if (callee_locals > sender_callee_parameters) {
     // The caller frame may need extending to accommodate
     // non-parameter locals of the first unpacked interpreted frame.
     // Compute that adjustment.
-    caller_adjustment = last_frame_adjust(callee_parameters, callee_locals);
+    caller_adjustment = last_frame_adjust(sender_callee_parameters, callee_locals);
   }
 
-
   // If the sender is deoptimized the we must retrieve the address of the handler
   // since the frame will "magically" show the original pc before the deopt
   // and we'd undo the deopt.
@@ -569,6 +587,8 @@
   if (VerifyStack) {
     ResourceMark res_mark;
 
+    thread->validate_frame_layout();
+
     // Verify that the just-unpacked frames match the interpreter's
     // notions of expression stack and locals
     vframeArray* cur_array = thread->vframe_array_last();