mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 14:11:36 +00:00
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
Reviewed-by: kvn, coleenp
This commit is contained in:
parent
42e49be1bc
commit
e5357d4bee
@ -2176,6 +2176,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
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,
|
||||
|
||||
@ -423,25 +423,6 @@ bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||
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
|
||||
|
||||
@ -1623,6 +1623,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
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 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
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) {
|
||||
|
||||
@ -2339,14 +2339,15 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
@ -242,26 +242,6 @@ address InterpreterGenerator::generate_method_handle_entry(void) {
|
||||
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
|
||||
|
||||
@ -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) {
|
||||
|
||||
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
|
||||
|
||||
@ -1589,6 +1589,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
int tempcount,
|
||||
int popframe_extra_args,
|
||||
int moncount,
|
||||
int caller_actual_parameters,
|
||||
int callee_param_count,
|
||||
int callee_locals,
|
||||
frame* caller,
|
||||
|
||||
@ -1603,6 +1603,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
int tempcount,
|
||||
int popframe_extra_args,
|
||||
int moncount,
|
||||
int caller_actual_parameters,
|
||||
int callee_param_count,
|
||||
int callee_locals,
|
||||
frame* caller,
|
||||
|
||||
@ -1427,6 +1427,7 @@ int AbstractInterpreter::layout_activation(methodOop method,
|
||||
int tempcount,
|
||||
int popframe_extra_args,
|
||||
int moncount,
|
||||
int caller_actual_parameters,
|
||||
int callee_param_count,
|
||||
int callee_locals,
|
||||
frame* caller,
|
||||
|
||||
@ -82,24 +82,6 @@ bool AbstractInterpreter::can_be_compiled(methodHandle m) {
|
||||
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) {
|
||||
}
|
||||
|
||||
@ -175,19 +175,32 @@ class AbstractInterpreter: AllStatic {
|
||||
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);
|
||||
|
||||
@ -90,12 +90,14 @@ bool DeoptimizationMarker::_is_active = false;
|
||||
|
||||
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 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
||||
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 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
||||
// 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 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
||||
// 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 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
||||
|
||||
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 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
|
||||
|
||||
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 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
|
||||
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();
|
||||
|
||||
|
||||
@ -138,6 +138,9 @@ class Deoptimization : AllStatic {
|
||||
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 @@ class Deoptimization : AllStatic {
|
||||
// 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 @@ class Deoptimization : AllStatic {
|
||||
|
||||
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); }
|
||||
|
||||
@ -1452,13 +1452,26 @@ void FrameValues::validate() {
|
||||
|
||||
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);
|
||||
|
||||
@ -154,7 +154,8 @@ void vframeArrayElement::fill_in(compiledVFrame* vf) {
|
||||
|
||||
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 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters,
|
||||
temps + callee_parameters,
|
||||
popframe_preserved_args_size_in_words,
|
||||
locks,
|
||||
caller_actual_parameters,
|
||||
callee_parameters,
|
||||
callee_locals,
|
||||
caller,
|
||||
@ -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,
|
||||
bool is_top_frame,
|
||||
int popframe_extra_stack_expression_els) const {
|
||||
@ -426,6 +429,7 @@ int vframeArrayElement::on_stack_size(int callee_parameters,
|
||||
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::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
|
||||
// unpack_frame
|
||||
// [new interpreter frames ] (frames are skeletal but walkable)
|
||||
@ -525,7 +529,8 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode) {
|
||||
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 @@ void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode) {
|
||||
Deoptimization::unwind_callee_save_values(element(index)->iframe(), this);
|
||||
}
|
||||
caller_frame = *element(index)->iframe();
|
||||
caller_actual_parameters = callee_parameters;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -83,13 +83,15 @@ class vframeArrayElement : public _ValueObj {
|
||||
|
||||
// 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 @@ class vframeArray: public CHeapObj {
|
||||
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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user