diff --git a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp index 3f3370ef28f217ecd7ec3705f77b1def7ce544b7..6f8e35afdf4777b7170ce7ae5010aa430fe7b5ca 100644 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp @@ -1609,6 +1609,12 @@ int AbstractInterpreter::layout_activation(methodOop method, // and sender_sp is fp+8 intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1; +#ifdef ASSERT + if (caller->is_interpreted_frame()) { + assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement"); + } +#endif + interpreter_frame->interpreter_frame_set_locals(locals); BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); BasicObjectLock* monbot = montop - moncount; diff --git a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp index 9aa8c344665c418fc21123c0edba3ba5f07c083d..40c7d63e1651afb17779e3d2829c5d939df6431e 100644 --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp @@ -1622,6 +1622,12 @@ int AbstractInterpreter::layout_activation(methodOop method, // sender_sp is fp+16 XXX intptr_t* locals = interpreter_frame->sender_sp() + max_locals - 1; +#ifdef ASSERT + if (caller->is_interpreted_frame()) { + assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement"); + } +#endif + interpreter_frame->interpreter_frame_set_locals(locals); BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin(); BasicObjectLock* monbot = montop - moncount; diff --git a/src/share/vm/interpreter/bytecodeTracer.cpp b/src/share/vm/interpreter/bytecodeTracer.cpp index b9f64ed8c706c361fe3dba84e0e15f19b6e3f96d..e510358c9242b1ec5a0f787cc3eb986de651940a 100644 --- a/src/share/vm/interpreter/bytecodeTracer.cpp +++ b/src/share/vm/interpreter/bytecodeTracer.cpp @@ -241,7 +241,7 @@ bool BytecodePrinter::check_index(int i, int& cp_index, outputStream* st) { st->print_cr(" not secondary entry?", i); return false; } - i = cache->entry_at(i)->main_entry_index(); + i = cache->entry_at(i)->main_entry_index() + constantPoolOopDesc::CPCACHE_INDEX_TAG; goto check_cache_index; } else { st->print_cr(" not in cache[*]?", i); diff --git a/src/share/vm/runtime/deoptimization.cpp b/src/share/vm/runtime/deoptimization.cpp index db95badcdedf2b20577d683c0def15e2c6ef7ca3..0c36d2d0cabf32cb15fa128fc7ed61aa31465c2b 100644 --- a/src/share/vm/runtime/deoptimization.cpp +++ b/src/share/vm/runtime/deoptimization.cpp @@ -362,8 +362,6 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames); // +1 because we always have an interpreter return address for the final slot. address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1); - int callee_parameters = 0; - int callee_locals = 0; int popframe_extra_args = 0; // Create an interpreter return address for the stub to use as its return // address so the skeletal frames are perfectly walkable @@ -387,14 +385,20 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread // 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; + bool caller_was_method_handle = false; 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); + if (cur.code() == Bytecodes::_invokedynamic || + (cur.code() == Bytecodes::_invokevirtual && + method->constants()->klass_ref_at_noresolve(cur.index()) == vmSymbols::java_lang_invoke_MethodHandle() && + methodOopDesc::is_method_handle_invoke_name(cur.name()))) { + // Method handle invokes may involve fairly arbitrary chains of + // calls so it's impossible to know how much actual space the + // caller has for locals. + caller_was_method_handle = true; + } } // @@ -411,14 +415,15 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread // in the frame_sizes/frame_pcs so the assembly code can do a trivial walk. // so things look a little strange in this loop. // + int callee_parameters = 0; + int callee_locals = 0; for (int index = 0; index < array->frames(); index++ ) { // 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))) int caller_parms = callee_parameters; - if (index == array->frames() - 1) { - // Use the value from the interpreted caller - caller_parms = caller_actual_parameters; + if ((index == array->frames() - 1) && caller_was_method_handle) { + caller_parms = 0; } frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms, callee_parameters, @@ -460,13 +465,13 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread // QQQ I'd rather see this pushed down into last_frame_adjust // and have it take the sender (aka caller). - if (deopt_sender.is_compiled_frame()) { + if (deopt_sender.is_compiled_frame() || caller_was_method_handle) { caller_adjustment = last_frame_adjust(0, callee_locals); - } else if (callee_locals > caller_actual_parameters) { + } else if (callee_locals > callee_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(caller_actual_parameters, callee_locals); + caller_adjustment = last_frame_adjust(callee_parameters, callee_locals); } // If the sender is deoptimized the we must retrieve the address of the handler @@ -481,7 +486,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, caller_adjustment * BytesPerWord, - caller_actual_parameters, + caller_was_method_handle ? 0 : callee_parameters, number_of_frames, frame_sizes, frame_pcs, diff --git a/src/share/vm/runtime/frame.cpp b/src/share/vm/runtime/frame.cpp index e55543311e21e159f04eaecd1af75b837e43a36e..c3a08529a38f693ab90f13976ec1398599f31c03 100644 --- a/src/share/vm/runtime/frame.cpp +++ b/src/share/vm/runtime/frame.cpp @@ -1338,7 +1338,11 @@ void frame::describe(FrameValues& values, int frame_no) { // Label values common to most frames values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no)); values.describe(-1, sp(), err_msg("sp for #%d", frame_no)); - values.describe(-1, fp(), err_msg("fp for #%d", frame_no)); + if (is_compiled_frame()) { + values.describe(-1, sp() + _cb->frame_size(), err_msg("computed fp for #%d", frame_no)); + } else { + values.describe(-1, fp(), err_msg("fp for #%d", frame_no)); + } } if (is_interpreted_frame()) { methodOop m = interpreter_frame_method(); @@ -1450,9 +1454,8 @@ void FrameValues::validate() { } -void FrameValues::print() { +void FrameValues::print(JavaThread* thread) { _values.sort(compare); - 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 @@ -1460,12 +1463,22 @@ void FrameValues::print() { 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; + + if (thread == Thread::current()) { + while (!thread->is_in_stack((address)v0)) { + v0 = _values.at(++min_index).location; + } + while (!thread->is_in_stack((address)v1)) { + v1 = _values.at(--max_index).location; + } + } else { + while (!thread->on_local_stack((address)v0)) { + v0 = _values.at(++min_index).location; + } + while (!thread->on_local_stack((address)v1)) { + v1 = _values.at(--max_index).location; + } } intptr_t* min = MIN2(v0, v1); intptr_t* max = MAX2(v0, v1); diff --git a/src/share/vm/runtime/frame.hpp b/src/share/vm/runtime/frame.hpp index ec3e3e6ebe35afa46ffb73285c29ee1e0d23c8d0..ec00e3a68b3f954c62bb65d63e92be469eeb96b9 100644 --- a/src/share/vm/runtime/frame.hpp +++ b/src/share/vm/runtime/frame.hpp @@ -516,7 +516,7 @@ class FrameValues { void describe(int owner, intptr_t* location, const char* description, int priority = 0); void validate(); - void print(); + void print(JavaThread* thread); }; #endif diff --git a/src/share/vm/runtime/thread.cpp b/src/share/vm/runtime/thread.cpp index 2cc2dfe95b27252c15a102af8f3f8a3c82d8cb33..a8cbf854af0bbf14ec53c5308ef5f6de8d619579 100644 --- a/src/share/vm/runtime/thread.cpp +++ b/src/share/vm/runtime/thread.cpp @@ -2947,7 +2947,7 @@ void JavaThread::print_frame_layout(int depth, bool validate_only) { values.validate(); } else { tty->print_cr("[Describe stack layout]"); - values.print(); + values.print(this); } } #endif