# HG changeset patch # User never # Date 1305221342 25200 # Node ID 3d2ab563047a1dc7718b004634a3410e4a2e3b17 # Parent 3cfb240033d156123796c3f21133b92d7a6f6fb3 7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method Reviewed-by: kvn, coleenp diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/sparc/vm/cppInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Thu May 12 10:29:02 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, diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/sparc/vm/interpreter_sparc.cpp --- a/src/cpu/sparc/vm/interpreter_sparc.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/sparc/vm/interpreter_sparc.cpp Thu May 12 10:29:02 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 diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/sparc/vm/templateInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu May 12 10:29:02 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) { diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/x86/vm/cppInterpreter_x86.cpp --- a/src/cpu/x86/vm/cppInterpreter_x86.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp Thu May 12 10:29:02 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() diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/x86/vm/interpreter_x86_32.cpp --- a/src/cpu/x86/vm/interpreter_x86_32.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/x86/vm/interpreter_x86_32.cpp Thu May 12 10:29:02 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 diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/x86/vm/interpreter_x86_64.cpp --- a/src/cpu/x86/vm/interpreter_x86_64.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/x86/vm/interpreter_x86_64.cpp Thu May 12 10:29:02 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 diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/x86/vm/templateInterpreter_x86_32.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu May 12 10:29:02 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, diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu May 12 10:29:02 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, diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/zero/vm/cppInterpreter_zero.cpp --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp Thu May 12 10:29:02 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, diff -r 3cfb240033d1 -r 3d2ab563047a src/cpu/zero/vm/interpreter_zero.cpp --- a/src/cpu/zero/vm/interpreter_zero.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/cpu/zero/vm/interpreter_zero.cpp Thu May 12 10:29:02 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) { } diff -r 3cfb240033d1 -r 3d2ab563047a src/share/vm/interpreter/abstractInterpreter.hpp --- a/src/share/vm/interpreter/abstractInterpreter.hpp Mon May 09 19:45:52 2011 -0700 +++ b/src/share/vm/interpreter/abstractInterpreter.hpp Thu May 12 10:29:02 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); diff -r 3cfb240033d1 -r 3d2ab563047a src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Mon May 09 19:45:52 2011 -0700 +++ b/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(); diff -r 3cfb240033d1 -r 3d2ab563047a src/share/vm/runtime/deoptimization.hpp --- a/src/share/vm/runtime/deoptimization.hpp Mon May 09 19:45:52 2011 -0700 +++ b/src/share/vm/runtime/deoptimization.hpp Thu May 12 10:29:02 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); } diff -r 3cfb240033d1 -r 3d2ab563047a src/share/vm/runtime/frame.cpp --- a/src/share/vm/runtime/frame.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/share/vm/runtime/frame.cpp Thu May 12 10:29:02 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); diff -r 3cfb240033d1 -r 3d2ab563047a src/share/vm/runtime/vframeArray.cpp --- a/src/share/vm/runtime/vframeArray.cpp Mon May 09 19:45:52 2011 -0700 +++ b/src/share/vm/runtime/vframeArray.cpp Thu May 12 10:29:02 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; } diff -r 3cfb240033d1 -r 3d2ab563047a src/share/vm/runtime/vframeArray.hpp --- a/src/share/vm/runtime/vframeArray.hpp Mon May 09 19:45:52 2011 -0700 +++ b/src/share/vm/runtime/vframeArray.hpp Thu May 12 10:29:02 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.