提交 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,
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.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册