--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Mon May 09 19:45:52 2011 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu May 12 10:29:02 2011 -0700
@@ -90,12 +90,14 @@
Deoptimization::UnrollBlock::UnrollBlock(int size_of_deoptimized_frame,
int caller_adjustment,
+ int caller_actual_parameters,
int number_of_frames,
intptr_t* frame_sizes,
address* frame_pcs,
BasicType return_type) {
_size_of_deoptimized_frame = size_of_deoptimized_frame;
_caller_adjustment = caller_adjustment;
+ _caller_actual_parameters = caller_actual_parameters;
_number_of_frames = number_of_frames;
_frame_sizes = frame_sizes;
_frame_pcs = frame_pcs;
@@ -373,6 +375,28 @@
popframe_extra_args = in_words(thread->popframe_preserved_args_size_in_words());
}
+ // Find the current pc for sender of the deoptee. Since the sender may have been deoptimized
+ // itself since the deoptee vframeArray was created we must get a fresh value of the pc rather
+ // than simply use array->sender.pc(). This requires us to walk the current set of frames
+ //
+ 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 caller_actual_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);
+ caller_actual_parameters = asc.size() + (cur.has_receiver() ? 1 : 0);
+ }
+
//
// frame_sizes/frame_pcs[0] oldest frame (int or c2i)
// frame_sizes/frame_pcs[1] next oldest frame (int)
@@ -391,7 +415,13 @@
// frame[number_of_frames - 1 ] = on_stack_size(youngest)
// frame[number_of_frames - 2 ] = on_stack_size(sender(youngest))
// frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest)))
- frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(callee_parameters,
+ int caller_parms = callee_parameters;
+ if (index == array->frames() - 1) {
+ // Use the value from the interpreted caller
+ caller_parms = caller_actual_parameters;
+ }
+ frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms,
+ callee_parameters,
callee_locals,
index == 0,
popframe_extra_args);
@@ -418,28 +448,6 @@
// Compute information for handling adapters and adjusting the frame size of the caller.
int caller_adjustment = 0;
- // Find the current pc for sender of the deoptee. Since the sender may have been deoptimized
- // itself since the deoptee vframeArray was created we must get a fresh value of the pc rather
- // than simply use array->sender.pc(). This requires us to walk the current set of frames
- //
- 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
@@ -454,11 +462,11 @@
if (deopt_sender.is_compiled_frame()) {
caller_adjustment = last_frame_adjust(0, callee_locals);
- } else if (callee_locals > sender_callee_parameters) {
+ } else if (callee_locals > caller_actual_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(sender_callee_parameters, callee_locals);
+ caller_adjustment = last_frame_adjust(caller_actual_parameters, callee_locals);
}
// If the sender is deoptimized the we must retrieve the address of the handler
@@ -473,6 +481,7 @@
UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
caller_adjustment * BytesPerWord,
+ caller_actual_parameters,
number_of_frames,
frame_sizes,
frame_pcs,
@@ -570,7 +579,7 @@
UnrollBlock* info = array->unroll_block();
// Unpack the interpreter frames and any adapter frame (c2 only) we might create.
- array->unpack_to_stack(stub_frame, exec_mode);
+ array->unpack_to_stack(stub_frame, exec_mode, info->caller_actual_parameters());
BasicType bt = info->return_type();