--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Thu May 12 10:33:17 2011 -0700
@@ -2176,6 +2176,7 @@
int tempcount, // Number of slots on java expression stack in use
int popframe_extra_args,
int moncount, // Number of active monitors
+ int caller_actual_parameters,
int callee_param_size,
int callee_locals_size,
frame* caller,
--- a/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp Thu May 12 10:33:17 2011 -0700
@@ -423,25 +423,6 @@
return true;
}
-// This method tells the deoptimizer how big an interpreted frame must be:
-int AbstractInterpreter::size_activation(methodOop method,
- int tempcount,
- int popframe_extra_args,
- int moncount,
- int callee_param_count,
- int callee_locals,
- bool is_top_frame) {
- return layout_activation(method,
- tempcount,
- popframe_extra_args,
- moncount,
- callee_param_count,
- callee_locals,
- (frame*)NULL,
- (frame*)NULL,
- is_top_frame);
-}
-
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu May 12 10:33:17 2011 -0700
@@ -1623,6 +1623,7 @@
int tempcount,
int popframe_extra_args,
int moncount,
+ int caller_actual_parameters,
int callee_param_count,
int callee_local_count,
frame* caller,
@@ -1698,24 +1699,35 @@
popframe_extra_args;
int local_words = method->max_locals() * Interpreter::stackElementWords;
+ NEEDS_CLEANUP;
intptr_t* locals;
- if (caller->is_compiled_frame()) {
- // Compiled frames do not allocate a varargs area so place them
- // next to the register save area.
- locals = fp + frame::register_save_words + local_words - 1;
- // Caller wants his own SP back
- int caller_frame_size = caller->cb()->frame_size();
- *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS;
+ if (caller->is_interpreted_frame()) {
+ // Can force the locals area to end up properly overlapping the top of the expression stack.
+ intptr_t* Lesp_ptr = caller->interpreter_frame_tos_address() - 1;
+ // Note that this computation means we replace size_of_parameters() values from the caller
+ // interpreter frame's expression stack with our argument locals
+ int parm_words = caller_actual_parameters * Interpreter::stackElementWords;
+ locals = Lesp_ptr + parm_words;
+ int delta = local_words - parm_words;
+ int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
+ *interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS;
} else {
- assert(caller->is_interpreted_frame() || caller->is_entry_frame(), "only possible cases");
- // The entry and interpreter frames are laid out like normal C
- // frames so place the locals adjacent to the varargs area.
- locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1;
- if (caller->is_interpreted_frame()) {
- int parm_words = method->size_of_parameters() * Interpreter::stackElementWords;
- int delta = local_words - parm_words;
- int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
- *interpreter_frame->register_addr(I5_savedSP) = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS;
+ assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases");
+ // Don't have Lesp available; lay out locals block in the caller
+ // adjacent to the register window save area.
+ //
+ // Compiled frames do not allocate a varargs area which is why this if
+ // statement is needed.
+ //
+ if (caller->is_compiled_frame()) {
+ locals = fp + frame::register_save_words + local_words - 1;
+ } else {
+ locals = fp + frame::memory_parameter_word_sp_offset + local_words - 1;
+ }
+ if (!caller->is_entry_frame()) {
+ // Caller wants his own SP back
+ int caller_frame_size = caller->cb()->frame_size();
+ *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS;
}
}
if (TraceDeoptimization) {
--- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp Thu May 12 10:33:17 2011 -0700
@@ -2339,14 +2339,15 @@
}
int AbstractInterpreter::layout_activation(methodOop method,
- int tempcount, //
- int popframe_extra_args,
- int moncount,
- int callee_param_count,
- int callee_locals,
- frame* caller,
- frame* interpreter_frame,
- bool is_top_frame) {
+ int tempcount, //
+ int popframe_extra_args,
+ int moncount,
+ int caller_actual_parameters,
+ int callee_param_count,
+ int callee_locals,
+ frame* caller,
+ frame* interpreter_frame,
+ bool is_top_frame) {
assert(popframe_extra_args == 0, "FIX ME");
// NOTE this code must exactly mimic what InterpreterGenerator::generate_compute_interpreter_state()
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp Thu May 12 10:33:17 2011 -0700
@@ -242,26 +242,6 @@
return entry_point;
}
-
-// This method tells the deoptimizer how big an interpreted frame must be:
-int AbstractInterpreter::size_activation(methodOop method,
- int tempcount,
- int popframe_extra_args,
- int moncount,
- int callee_param_count,
- int callee_locals,
- bool is_top_frame) {
- return layout_activation(method,
- tempcount,
- popframe_extra_args,
- moncount,
- callee_param_count,
- callee_locals,
- (frame*) NULL,
- (frame*) NULL,
- is_top_frame);
-}
-
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp Thu May 12 10:33:17 2011 -0700
@@ -362,20 +362,6 @@
}
-// This method tells the deoptimizer how big an interpreted frame must be:
-int AbstractInterpreter::size_activation(methodOop method,
- int tempcount,
- int popframe_extra_args,
- int moncount,
- int callee_param_count,
- int callee_locals,
- bool is_top_frame) {
- return layout_activation(method,
- tempcount, popframe_extra_args, moncount,
- callee_param_count, callee_locals,
- (frame*) NULL, (frame*) NULL, is_top_frame);
-}
-
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu May 12 10:33:17 2011 -0700
@@ -1589,6 +1589,7 @@
int tempcount,
int popframe_extra_args,
int moncount,
+ int caller_actual_parameters,
int callee_param_count,
int callee_locals,
frame* caller,
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu May 12 10:33:17 2011 -0700
@@ -1603,6 +1603,7 @@
int tempcount,
int popframe_extra_args,
int moncount,
+ int caller_actual_parameters,
int callee_param_count,
int callee_locals,
frame* caller,
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu May 12 10:33:17 2011 -0700
@@ -1427,6 +1427,7 @@
int tempcount,
int popframe_extra_args,
int moncount,
+ int caller_actual_parameters,
int callee_param_count,
int callee_locals,
frame* caller,
--- a/hotspot/src/cpu/zero/vm/interpreter_zero.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/cpu/zero/vm/interpreter_zero.cpp Thu May 12 10:33:17 2011 -0700
@@ -82,24 +82,6 @@
return true;
}
-int AbstractInterpreter::size_activation(methodOop method,
- int tempcount,
- int popframe_extra_args,
- int moncount,
- int callee_param_count,
- int callee_locals,
- bool is_top_frame) {
- return layout_activation(method,
- tempcount,
- popframe_extra_args,
- moncount,
- callee_param_count,
- callee_locals,
- (frame*) NULL,
- (frame*) NULL,
- is_top_frame);
-}
-
void Deoptimization::unwind_callee_save_values(frame* f,
vframeArray* vframe_array) {
}
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp Thu May 12 10:33:17 2011 -0700
@@ -175,19 +175,32 @@
int temps,
int popframe_args,
int monitors,
+ int caller_actual_parameters,
int callee_params,
int callee_locals,
- bool is_top_frame);
+ bool is_top_frame) {
+ return layout_activation(method,
+ temps,
+ popframe_args,
+ monitors,
+ caller_actual_parameters,
+ callee_params,
+ callee_locals,
+ (frame*)NULL,
+ (frame*)NULL,
+ is_top_frame);
+ }
static int layout_activation(methodOop method,
- int temps,
- int popframe_args,
- int monitors,
- int callee_params,
- int callee_locals,
- frame* caller,
- frame* interpreter_frame,
- bool is_top_frame);
+ int temps,
+ int popframe_args,
+ int monitors,
+ int caller_actual_parameters,
+ int callee_params,
+ int callee_locals,
+ frame* caller,
+ frame* interpreter_frame,
+ bool is_top_frame);
// Runtime support
static bool is_not_reached( methodHandle method, int bci);
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Thu May 12 10:33:17 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();
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp Thu May 12 10:33:17 2011 -0700
@@ -138,6 +138,9 @@
intptr_t* _register_block; // Block for storing callee-saved registers.
BasicType _return_type; // Tells if we have to restore double or long return value
intptr_t _initial_fp; // FP of the sender frame
+ int _caller_actual_parameters; // The number of actual arguments at the
+ // interpreted caller of the deoptimized frame
+
// The following fields are used as temps during the unpacking phase
// (which is tight on registers, especially on x86). They really ought
// to be PD variables but that involves moving this class into its own
@@ -149,6 +152,7 @@
// Constructor
UnrollBlock(int size_of_deoptimized_frame,
int caller_adjustment,
+ int caller_actual_parameters,
int number_of_frames,
intptr_t* frame_sizes,
address* frames_pcs,
@@ -168,6 +172,8 @@
void set_initial_fp(intptr_t fp) { _initial_fp = fp; }
+ int caller_actual_parameters() const { return _caller_actual_parameters; }
+
// Accessors used by the code generator for the unpack stub.
static int size_of_deoptimized_frame_offset_in_bytes() { return offset_of(UnrollBlock, _size_of_deoptimized_frame); }
static int caller_adjustment_offset_in_bytes() { return offset_of(UnrollBlock, _caller_adjustment); }
--- a/hotspot/src/share/vm/runtime/frame.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/share/vm/runtime/frame.cpp Thu May 12 10:33:17 2011 -0700
@@ -1452,13 +1452,26 @@
void FrameValues::print() {
_values.sort(compare);
- intptr_t* v0 = _values.at(0).location;
- intptr_t* v1 = _values.at(_values.length() - 1).location;
+ JavaThread* thread = JavaThread::current();
+
+ // Sometimes values like the fp can be invalid values if the
+ // register map wasn't updated during the walk. Trim out values
+ // that aren't actually in the stack of the thread.
+ int min_index = 0;
+ int max_index = _values.length() - 1;
+ intptr_t* v0 = _values.at(min_index).location;
+ while (!thread->is_in_stack((address)v0)) {
+ v0 = _values.at(++min_index).location;
+ }
+ intptr_t* v1 = _values.at(max_index).location;
+ while (!thread->is_in_stack((address)v1)) {
+ v1 = _values.at(--max_index).location;
+ }
intptr_t* min = MIN2(v0, v1);
intptr_t* max = MAX2(v0, v1);
intptr_t* cur = max;
intptr_t* last = NULL;
- for (int i = _values.length() - 1; i >= 0; i--) {
+ for (int i = max_index; i >= min_index; i--) {
FrameValue fv = _values.at(i);
while (cur > fv.location) {
tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT, cur, *cur);
--- a/hotspot/src/share/vm/runtime/vframeArray.cpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/share/vm/runtime/vframeArray.cpp Thu May 12 10:33:17 2011 -0700
@@ -154,7 +154,8 @@
int unpack_counter = 0;
-void vframeArrayElement::unpack_on_stack(int callee_parameters,
+void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
+ int callee_parameters,
int callee_locals,
frame* caller,
bool is_top_frame,
@@ -270,6 +271,7 @@
temps + callee_parameters,
popframe_preserved_args_size_in_words,
locks,
+ caller_actual_parameters,
callee_parameters,
callee_locals,
caller,
@@ -415,7 +417,8 @@
}
-int vframeArrayElement::on_stack_size(int callee_parameters,
+int vframeArrayElement::on_stack_size(int caller_actual_parameters,
+ int callee_parameters,
int callee_locals,
bool is_top_frame,
int popframe_extra_stack_expression_els) const {
@@ -426,6 +429,7 @@
temps + callee_parameters,
popframe_extra_stack_expression_els,
locks,
+ caller_actual_parameters,
callee_parameters,
callee_locals,
is_top_frame);
@@ -496,7 +500,7 @@
}
}
-void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode) {
+void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller_actual_parameters) {
// stack picture
// unpack_frame
// [new interpreter frames ] (frames are skeletal but walkable)
@@ -525,7 +529,8 @@
for (index = frames() - 1; index >= 0 ; index--) {
int callee_parameters = index == 0 ? 0 : element(index-1)->method()->size_of_parameters();
int callee_locals = index == 0 ? 0 : element(index-1)->method()->max_locals();
- element(index)->unpack_on_stack(callee_parameters,
+ element(index)->unpack_on_stack(caller_actual_parameters,
+ callee_parameters,
callee_locals,
&caller_frame,
index == 0,
@@ -534,6 +539,7 @@
Deoptimization::unwind_callee_save_values(element(index)->iframe(), this);
}
caller_frame = *element(index)->iframe();
+ caller_actual_parameters = callee_parameters;
}
--- a/hotspot/src/share/vm/runtime/vframeArray.hpp Tue May 10 17:44:14 2011 -0700
+++ b/hotspot/src/share/vm/runtime/vframeArray.hpp Thu May 12 10:33:17 2011 -0700
@@ -83,13 +83,15 @@
// Returns the on stack word size for this frame
// callee_parameters is the number of callee locals residing inside this frame
- int on_stack_size(int callee_parameters,
+ int on_stack_size(int caller_actual_parameters,
+ int callee_parameters,
int callee_locals,
bool is_top_frame,
int popframe_extra_stack_expression_els) const;
// Unpacks the element to skeletal interpreter frame
- void unpack_on_stack(int callee_parameters,
+ void unpack_on_stack(int caller_actual_parameters,
+ int callee_parameters,
int callee_locals,
frame* caller,
bool is_top_frame,
@@ -190,7 +192,7 @@
int frame_size() const { return _frame_size; }
// Unpack the array on the stack passed in stack interval
- void unpack_to_stack(frame &unpack_frame, int exec_mode);
+ void unpack_to_stack(frame &unpack_frame, int exec_mode, int caller_actual_parameters);
// Deallocates monitor chunks allocated during deoptimization.
// This should be called when the array is not used anymore.