提交 d87460b9 编写于 作者: N never

7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method

Reviewed-by: kvn, coleenp
上级 653ef337
...@@ -2176,6 +2176,7 @@ int AbstractInterpreter::layout_activation(methodOop method, ...@@ -2176,6 +2176,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
int tempcount, // Number of slots on java expression stack in use int tempcount, // Number of slots on java expression stack in use
int popframe_extra_args, int popframe_extra_args,
int moncount, // Number of active monitors int moncount, // Number of active monitors
int caller_actual_parameters,
int callee_param_size, int callee_param_size,
int callee_locals_size, int callee_locals_size,
frame* caller, frame* caller,
......
...@@ -423,25 +423,6 @@ bool AbstractInterpreter::can_be_compiled(methodHandle m) { ...@@ -423,25 +423,6 @@ bool AbstractInterpreter::can_be_compiled(methodHandle m) {
return true; 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) { 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 // This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
......
...@@ -1623,6 +1623,7 @@ int AbstractInterpreter::layout_activation(methodOop method, ...@@ -1623,6 +1623,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
int tempcount, int tempcount,
int popframe_extra_args, int popframe_extra_args,
int moncount, int moncount,
int caller_actual_parameters,
int callee_param_count, int callee_param_count,
int callee_local_count, int callee_local_count,
frame* caller, frame* caller,
...@@ -1698,24 +1699,35 @@ int AbstractInterpreter::layout_activation(methodOop method, ...@@ -1698,24 +1699,35 @@ int AbstractInterpreter::layout_activation(methodOop method,
popframe_extra_args; popframe_extra_args;
int local_words = method->max_locals() * Interpreter::stackElementWords; int local_words = method->max_locals() * Interpreter::stackElementWords;
NEEDS_CLEANUP;
intptr_t* locals; intptr_t* locals;
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_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()) { 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; 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 // Caller wants his own SP back
int caller_frame_size = caller->cb()->frame_size(); int caller_frame_size = caller->cb()->frame_size();
*interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - STACK_BIAS; *interpreter_frame->register_addr(I5_savedSP) = (intptr_t)(caller->fp() - caller_frame_size) - 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;
} }
} }
if (TraceDeoptimization) { if (TraceDeoptimization) {
......
...@@ -2342,6 +2342,7 @@ int AbstractInterpreter::layout_activation(methodOop method, ...@@ -2342,6 +2342,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
int tempcount, // int tempcount, //
int popframe_extra_args, int popframe_extra_args,
int moncount, int moncount,
int caller_actual_parameters,
int callee_param_count, int callee_param_count,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
......
...@@ -242,26 +242,6 @@ address InterpreterGenerator::generate_method_handle_entry(void) { ...@@ -242,26 +242,6 @@ address InterpreterGenerator::generate_method_handle_entry(void) {
return entry_point; 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) { 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 // This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
......
...@@ -362,20 +362,6 @@ address InterpreterGenerator::generate_empty_entry(void) { ...@@ -362,20 +362,6 @@ address InterpreterGenerator::generate_empty_entry(void) {
} }
// 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) { 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 // This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
......
...@@ -1589,6 +1589,7 @@ int AbstractInterpreter::layout_activation(methodOop method, ...@@ -1589,6 +1589,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
int tempcount, int tempcount,
int popframe_extra_args, int popframe_extra_args,
int moncount, int moncount,
int caller_actual_parameters,
int callee_param_count, int callee_param_count,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
......
...@@ -1603,6 +1603,7 @@ int AbstractInterpreter::layout_activation(methodOop method, ...@@ -1603,6 +1603,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
int tempcount, int tempcount,
int popframe_extra_args, int popframe_extra_args,
int moncount, int moncount,
int caller_actual_parameters,
int callee_param_count, int callee_param_count,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
......
...@@ -1427,6 +1427,7 @@ int AbstractInterpreter::layout_activation(methodOop method, ...@@ -1427,6 +1427,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
int tempcount, int tempcount,
int popframe_extra_args, int popframe_extra_args,
int moncount, int moncount,
int caller_actual_parameters,
int callee_param_count, int callee_param_count,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
......
...@@ -82,24 +82,6 @@ bool AbstractInterpreter::can_be_compiled(methodHandle m) { ...@@ -82,24 +82,6 @@ bool AbstractInterpreter::can_be_compiled(methodHandle m) {
return true; 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, void Deoptimization::unwind_callee_save_values(frame* f,
vframeArray* vframe_array) { vframeArray* vframe_array) {
} }
...@@ -175,14 +175,27 @@ class AbstractInterpreter: AllStatic { ...@@ -175,14 +175,27 @@ class AbstractInterpreter: AllStatic {
int temps, int temps,
int popframe_args, int popframe_args,
int monitors, int monitors,
int caller_actual_parameters,
int callee_params, int callee_params,
int callee_locals, 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, static int layout_activation(methodOop method,
int temps, int temps,
int popframe_args, int popframe_args,
int monitors, int monitors,
int caller_actual_parameters,
int callee_params, int callee_params,
int callee_locals, int callee_locals,
frame* caller, frame* caller,
......
...@@ -90,12 +90,14 @@ bool DeoptimizationMarker::_is_active = false; ...@@ -90,12 +90,14 @@ bool DeoptimizationMarker::_is_active = false;
Deoptimization::UnrollBlock::UnrollBlock(int size_of_deoptimized_frame, Deoptimization::UnrollBlock::UnrollBlock(int size_of_deoptimized_frame,
int caller_adjustment, int caller_adjustment,
int caller_actual_parameters,
int number_of_frames, int number_of_frames,
intptr_t* frame_sizes, intptr_t* frame_sizes,
address* frame_pcs, address* frame_pcs,
BasicType return_type) { BasicType return_type) {
_size_of_deoptimized_frame = size_of_deoptimized_frame; _size_of_deoptimized_frame = size_of_deoptimized_frame;
_caller_adjustment = caller_adjustment; _caller_adjustment = caller_adjustment;
_caller_actual_parameters = caller_actual_parameters;
_number_of_frames = number_of_frames; _number_of_frames = number_of_frames;
_frame_sizes = frame_sizes; _frame_sizes = frame_sizes;
_frame_pcs = frame_pcs; _frame_pcs = frame_pcs;
...@@ -373,6 +375,28 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread ...@@ -373,6 +375,28 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
popframe_extra_args = in_words(thread->popframe_preserved_args_size_in_words()); 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[0] oldest frame (int or c2i)
// frame_sizes/frame_pcs[1] next oldest frame (int) // frame_sizes/frame_pcs[1] next oldest frame (int)
...@@ -391,7 +415,13 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread ...@@ -391,7 +415,13 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
// frame[number_of_frames - 1 ] = on_stack_size(youngest) // frame[number_of_frames - 1 ] = on_stack_size(youngest)
// frame[number_of_frames - 2 ] = on_stack_size(sender(youngest)) // frame[number_of_frames - 2 ] = on_stack_size(sender(youngest))
// frame[number_of_frames - 3 ] = on_stack_size(sender(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, callee_locals,
index == 0, index == 0,
popframe_extra_args); popframe_extra_args);
...@@ -418,28 +448,6 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread ...@@ -418,28 +448,6 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
// Compute information for handling adapters and adjusting the frame size of the caller. // Compute information for handling adapters and adjusting the frame size of the caller.
int caller_adjustment = 0; 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 // Compute the amount the oldest interpreter frame will have to adjust
// its caller's stack by. If the caller is a compiled frame then // its caller's stack by. If the caller is a compiled frame then
// we pretend that the callee has no parameters so that the // we pretend that the callee has no parameters so that the
...@@ -454,11 +462,11 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread ...@@ -454,11 +462,11 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
if (deopt_sender.is_compiled_frame()) { if (deopt_sender.is_compiled_frame()) {
caller_adjustment = last_frame_adjust(0, callee_locals); 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 // The caller frame may need extending to accommodate
// non-parameter locals of the first unpacked interpreted frame. // non-parameter locals of the first unpacked interpreted frame.
// Compute that adjustment. // 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 // If the sender is deoptimized the we must retrieve the address of the handler
...@@ -473,6 +481,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread ...@@ -473,6 +481,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
caller_adjustment * BytesPerWord, caller_adjustment * BytesPerWord,
caller_actual_parameters,
number_of_frames, number_of_frames,
frame_sizes, frame_sizes,
frame_pcs, frame_pcs,
...@@ -570,7 +579,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m ...@@ -570,7 +579,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
UnrollBlock* info = array->unroll_block(); UnrollBlock* info = array->unroll_block();
// Unpack the interpreter frames and any adapter frame (c2 only) we might create. // 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(); BasicType bt = info->return_type();
......
...@@ -138,6 +138,9 @@ class Deoptimization : AllStatic { ...@@ -138,6 +138,9 @@ class Deoptimization : AllStatic {
intptr_t* _register_block; // Block for storing callee-saved registers. intptr_t* _register_block; // Block for storing callee-saved registers.
BasicType _return_type; // Tells if we have to restore double or long return value BasicType _return_type; // Tells if we have to restore double or long return value
intptr_t _initial_fp; // FP of the sender frame 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 // The following fields are used as temps during the unpacking phase
// (which is tight on registers, especially on x86). They really ought // (which is tight on registers, especially on x86). They really ought
// to be PD variables but that involves moving this class into its own // to be PD variables but that involves moving this class into its own
...@@ -149,6 +152,7 @@ class Deoptimization : AllStatic { ...@@ -149,6 +152,7 @@ class Deoptimization : AllStatic {
// Constructor // Constructor
UnrollBlock(int size_of_deoptimized_frame, UnrollBlock(int size_of_deoptimized_frame,
int caller_adjustment, int caller_adjustment,
int caller_actual_parameters,
int number_of_frames, int number_of_frames,
intptr_t* frame_sizes, intptr_t* frame_sizes,
address* frames_pcs, address* frames_pcs,
...@@ -168,6 +172,8 @@ class Deoptimization : AllStatic { ...@@ -168,6 +172,8 @@ class Deoptimization : AllStatic {
void set_initial_fp(intptr_t fp) { _initial_fp = fp; } 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. // 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 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); } static int caller_adjustment_offset_in_bytes() { return offset_of(UnrollBlock, _caller_adjustment); }
......
...@@ -1452,13 +1452,26 @@ void FrameValues::validate() { ...@@ -1452,13 +1452,26 @@ void FrameValues::validate() {
void FrameValues::print() { void FrameValues::print() {
_values.sort(compare); _values.sort(compare);
intptr_t* v0 = _values.at(0).location; JavaThread* thread = JavaThread::current();
intptr_t* v1 = _values.at(_values.length() - 1).location;
// 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* min = MIN2(v0, v1);
intptr_t* max = MAX2(v0, v1); intptr_t* max = MAX2(v0, v1);
intptr_t* cur = max; intptr_t* cur = max;
intptr_t* last = NULL; 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); FrameValue fv = _values.at(i);
while (cur > fv.location) { while (cur > fv.location) {
tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT, cur, *cur); tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT, cur, *cur);
......
...@@ -154,7 +154,8 @@ void vframeArrayElement::fill_in(compiledVFrame* vf) { ...@@ -154,7 +154,8 @@ void vframeArrayElement::fill_in(compiledVFrame* vf) {
int unpack_counter = 0; 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, int callee_locals,
frame* caller, frame* caller,
bool is_top_frame, bool is_top_frame,
...@@ -270,6 +271,7 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters, ...@@ -270,6 +271,7 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters,
temps + callee_parameters, temps + callee_parameters,
popframe_preserved_args_size_in_words, popframe_preserved_args_size_in_words,
locks, locks,
caller_actual_parameters,
callee_parameters, callee_parameters,
callee_locals, callee_locals,
caller, caller,
...@@ -415,7 +417,8 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters, ...@@ -415,7 +417,8 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters,
} }
int vframeArrayElement::on_stack_size(int callee_parameters, int vframeArrayElement::on_stack_size(int caller_actual_parameters,
int callee_parameters,
int callee_locals, int callee_locals,
bool is_top_frame, bool is_top_frame,
int popframe_extra_stack_expression_els) const { int popframe_extra_stack_expression_els) const {
...@@ -426,6 +429,7 @@ int vframeArrayElement::on_stack_size(int callee_parameters, ...@@ -426,6 +429,7 @@ int vframeArrayElement::on_stack_size(int callee_parameters,
temps + callee_parameters, temps + callee_parameters,
popframe_extra_stack_expression_els, popframe_extra_stack_expression_els,
locks, locks,
caller_actual_parameters,
callee_parameters, callee_parameters,
callee_locals, callee_locals,
is_top_frame); is_top_frame);
...@@ -496,7 +500,7 @@ void vframeArray::fill_in(JavaThread* thread, ...@@ -496,7 +500,7 @@ void vframeArray::fill_in(JavaThread* thread,
} }
} }
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 // stack picture
// unpack_frame // unpack_frame
// [new interpreter frames ] (frames are skeletal but walkable) // [new interpreter frames ] (frames are skeletal but walkable)
...@@ -525,7 +529,8 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode) { ...@@ -525,7 +529,8 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode) {
for (index = frames() - 1; index >= 0 ; index--) { for (index = frames() - 1; index >= 0 ; index--) {
int callee_parameters = index == 0 ? 0 : element(index-1)->method()->size_of_parameters(); 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(); 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, callee_locals,
&caller_frame, &caller_frame,
index == 0, index == 0,
...@@ -534,6 +539,7 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode) { ...@@ -534,6 +539,7 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode) {
Deoptimization::unwind_callee_save_values(element(index)->iframe(), this); Deoptimization::unwind_callee_save_values(element(index)->iframe(), this);
} }
caller_frame = *element(index)->iframe(); caller_frame = *element(index)->iframe();
caller_actual_parameters = callee_parameters;
} }
......
...@@ -83,13 +83,15 @@ class vframeArrayElement : public _ValueObj { ...@@ -83,13 +83,15 @@ class vframeArrayElement : public _ValueObj {
// Returns the on stack word size for this frame // Returns the on stack word size for this frame
// callee_parameters is the number of callee locals residing inside 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, int callee_locals,
bool is_top_frame, bool is_top_frame,
int popframe_extra_stack_expression_els) const; int popframe_extra_stack_expression_els) const;
// Unpacks the element to skeletal interpreter frame // 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, int callee_locals,
frame* caller, frame* caller,
bool is_top_frame, bool is_top_frame,
...@@ -190,7 +192,7 @@ class vframeArray: public CHeapObj { ...@@ -190,7 +192,7 @@ class vframeArray: public CHeapObj {
int frame_size() const { return _frame_size; } int frame_size() const { return _frame_size; }
// Unpack the array on the stack passed in stack interval // 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. // Deallocates monitor chunks allocated during deoptimization.
// This should be called when the array is not used anymore. // This should be called when the array is not used anymore.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册