src/share/vm/runtime/sharedRuntime.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/runtime/sharedRuntime.cpp

src/share/vm/runtime/sharedRuntime.cpp

Print this page

        

*** 1068,1077 **** --- 1068,1092 ---- vframeStream vfst(thread, true); // Do not skip and javaCalls return find_callee_info_helper(thread, vfst, bc, callinfo, THREAD); } + methodHandle SharedRuntime::extract_attached_method(vframeStream& vfst) { + nmethod* caller_nm = vfst.nm(); + + nmethodLocker caller_lock(caller_nm); + + address pc = vfst.frame_pc(); + { // Get call instruction under lock because another thread may be busy patching it. + MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag); + if (NativeCall::is_call_before(pc)) { + NativeCall* ncall = nativeCall_before(pc); + return caller_nm->attached_method(ncall->instruction_address()); + } + } + return NULL; + } // Finds receiver, CallInfo (i.e. receiver method), and calling bytecode // for a call current in progress, i.e., arguments has been pushed on stack // but callee has not been invoked yet. Caller frame must be compiled. Handle SharedRuntime::find_callee_info_helper(JavaThread* thread,
*** 1085,1142 **** // Find caller and bci from vframe methodHandle caller(THREAD, vfst.method()); int bci = vfst.bci(); - // Find bytecode Bytecode_invoke bytecode(caller, bci); - bc = bytecode.invoke_code(); int bytecode_index = bytecode.index(); ! // Find receiver for non-static call ! if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic && ! bc != Bytecodes::_invokehandle) { // This register map must be update since we need to find the receiver for // compiled frames. The receiver might be in a register. RegisterMap reg_map2(thread); frame stubFrame = thread->last_frame(); // Caller-frame is a compiled frame frame callerFrame = stubFrame.sender(&reg_map2); ! methodHandle callee = bytecode.static_target(CHECK_(nullHandle)); if (callee.is_null()) { THROW_(vmSymbols::java_lang_NoSuchMethodException(), nullHandle); } // Retrieve from a compiled argument list receiver = Handle(THREAD, callerFrame.retrieve_receiver(&reg_map2)); if (receiver.is_null()) { THROW_(vmSymbols::java_lang_NullPointerException(), nullHandle); } } - // Resolve method. This is parameterized by bytecode. - constantPoolHandle constants(THREAD, caller->constants()); assert(receiver.is_null() || receiver->is_oop(), "wrong receiver"); ! LinkResolver::resolve_invoke(callinfo, receiver, constants, bytecode_index, bc, CHECK_(nullHandle)); #ifdef ASSERT // Check that the receiver klass is of the right subtype and that it is initialized for virtual calls ! if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic && bc != Bytecodes::_invokehandle) { assert(receiver.not_null(), "should have thrown exception"); KlassHandle receiver_klass(THREAD, receiver->klass()); ! Klass* rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle)); ! // klass is already loaded KlassHandle static_receiver_klass(THREAD, rk); - // Method handle invokes might have been optimized to a direct call - // so don't check for the receiver class. - // FIXME this weakens the assert too much methodHandle callee = callinfo.selected_method(); ! assert(receiver_klass->is_subtype_of(static_receiver_klass()) || ! callee->is_method_handle_intrinsic() || ! callee->is_compiled_lambda_form(), "actual receiver must be subclass of static receiver klass"); if (receiver_klass->is_instance_klass()) { if (InstanceKlass::cast(receiver_klass())->is_not_initialized()) { tty->print_cr("ERROR: Klass not yet initialized!!"); receiver_klass()->print(); --- 1100,1191 ---- // Find caller and bci from vframe methodHandle caller(THREAD, vfst.method()); int bci = vfst.bci(); Bytecode_invoke bytecode(caller, bci); int bytecode_index = bytecode.index(); ! methodHandle attached_method = extract_attached_method(vfst); ! if (attached_method.not_null()) { ! methodHandle callee = bytecode.static_target(CHECK_NH); ! vmIntrinsics::ID id = callee->intrinsic_id(); ! // When VM replaces MH.invokeBasic/linkTo* call with a direct/virtual call, ! // it attaches statically resolved method to the call site. ! if (MethodHandles::is_signature_polymorphic(id) && ! MethodHandles::is_signature_polymorphic_intrinsic(id)) { ! bc = MethodHandles::signature_polymorphic_intrinsic_bytecode(id); ! ! // Need to adjust invokehandle since inlining through signature-polymorphic ! // method happened. ! if (bc == Bytecodes::_invokehandle && ! !MethodHandles::is_signature_polymorphic_method(attached_method())) { ! bc = attached_method->is_static() ? Bytecodes::_invokestatic ! : Bytecodes::_invokevirtual; ! } ! } ! } else { ! bc = bytecode.invoke_code(); ! } ! ! bool has_receiver = bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic && ! bc != Bytecodes::_invokehandle; ! ! // Find receiver for non-static call ! if (has_receiver) { // This register map must be update since we need to find the receiver for // compiled frames. The receiver might be in a register. RegisterMap reg_map2(thread); frame stubFrame = thread->last_frame(); // Caller-frame is a compiled frame frame callerFrame = stubFrame.sender(&reg_map2); ! if (attached_method.is_null()) { ! methodHandle callee = bytecode.static_target(CHECK_NH); if (callee.is_null()) { THROW_(vmSymbols::java_lang_NoSuchMethodException(), nullHandle); } + } + // Retrieve from a compiled argument list receiver = Handle(THREAD, callerFrame.retrieve_receiver(&reg_map2)); if (receiver.is_null()) { THROW_(vmSymbols::java_lang_NullPointerException(), nullHandle); } } assert(receiver.is_null() || receiver->is_oop(), "wrong receiver"); ! ! // Resolve method ! if (attached_method.not_null()) { ! // Parameterized by attached method. ! LinkResolver::resolve_invoke(callinfo, receiver, attached_method, bc, CHECK_NH); ! } else { ! // Parameterized by bytecode. ! constantPoolHandle constants(THREAD, caller->constants()); ! LinkResolver::resolve_invoke(callinfo, receiver, constants, bytecode_index, bc, CHECK_NH); ! } #ifdef ASSERT // Check that the receiver klass is of the right subtype and that it is initialized for virtual calls ! if (has_receiver) { assert(receiver.not_null(), "should have thrown exception"); KlassHandle receiver_klass(THREAD, receiver->klass()); ! Klass* rk = NULL; ! if (attached_method.not_null()) { ! // In case there's resolved method attached, use its holder during the check. ! rk = attached_method->method_holder(); ! } else { ! // Klass is already loaded. ! constantPoolHandle constants(THREAD, caller->constants()); ! rk = constants->klass_ref_at(bytecode_index, CHECK_NH); ! } KlassHandle static_receiver_klass(THREAD, rk); methodHandle callee = callinfo.selected_method(); ! assert(receiver_klass->is_subtype_of(static_receiver_klass()), "actual receiver must be subclass of static receiver klass"); if (receiver_klass->is_instance_klass()) { if (InstanceKlass::cast(receiver_klass())->is_not_initialized()) { tty->print_cr("ERROR: Klass not yet initialized!!"); receiver_klass()->print();
*** 1668,1678 **** // compiled, dispatched call (which used to call an interpreted method) CompiledIC* inline_cache = CompiledIC_at(caller_nm, call_addr); inline_cache->set_to_clean(); } } - } methodHandle callee_method = find_callee_method(thread, CHECK_(methodHandle())); --- 1717,1726 ----
src/share/vm/runtime/sharedRuntime.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File