diff --git a/src/share/vm/ci/ciMethod.hpp b/src/share/vm/ci/ciMethod.hpp index 45a491f9d22a001889cd045eb56ba6e1f662c02f..98571ae28735e2966add51567a9161db2f02c06e 100644 --- a/src/share/vm/ci/ciMethod.hpp +++ b/src/share/vm/ci/ciMethod.hpp @@ -295,12 +295,6 @@ class ciMethod : public ciObject { // Print the name of this method in various incarnations. void print_name(outputStream* st = tty); void print_short_name(outputStream* st = tty); - - methodOop get_method_handle_target() { - KlassHandle receiver_limit; int flags = 0; - methodHandle m = MethodHandles::decode_method(get_oop(), receiver_limit, flags); - return m(); - } }; #endif // SHARE_VM_CI_CIMETHOD_HPP diff --git a/src/share/vm/opto/callGenerator.cpp b/src/share/vm/opto/callGenerator.cpp index 5ac338322ed4765222e9ef1599d54d20c7796198..6455c812567b65effaa67194afe601c5c1742274 100644 --- a/src/share/vm/opto/callGenerator.cpp +++ b/src/share/vm/opto/callGenerator.cpp @@ -318,17 +318,17 @@ CallGenerator* CallGenerator::for_direct_call(ciMethod* m, bool separate_io_proj return new DirectCallGenerator(m, separate_io_proj); } -CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) { - assert(m->is_method_handle_invoke() || m->is_method_handle_adapter(), "for_dynamic_call mismatch"); - return new DynamicCallGenerator(m); -} - CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) { assert(!m->is_static(), "for_virtual_call mismatch"); assert(!m->is_method_handle_invoke(), "should be a direct call"); return new VirtualCallGenerator(m, vtable_index); } +CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) { + assert(m->is_method_handle_invoke() || m->is_method_handle_adapter(), "for_dynamic_call mismatch"); + return new DynamicCallGenerator(m); +} + // Allow inlining decisions to be delayed class LateInlineCallGenerator : public DirectCallGenerator { CallGenerator* _inline_cg; @@ -576,7 +576,9 @@ JVMState* PredictedCallGenerator::generate(JVMState* jvms) { kit.set_control(slow_ctl); if (!kit.stopped()) { slow_jvms = _if_missed->generate(kit.sync_jvms()); - assert(slow_jvms != NULL, "miss path must not fail to generate"); + if (kit.failing()) + return NULL; // might happen because of NodeCountInliningCutoff + assert(slow_jvms != NULL, "must be"); kit.add_exception_states_from(slow_jvms); kit.set_map(slow_jvms->map()); if (!kit.stopped()) @@ -682,6 +684,15 @@ CallGenerator* CallGenerator::for_predicted_dynamic_call(ciMethodHandle* predict } +CallGenerator* CallGenerator::for_method_handle_call(Node* method_handle, JVMState* jvms, + ciMethod* caller, ciMethod* callee, ciCallProfile profile) { + assert(callee->is_method_handle_invoke() || callee->is_method_handle_adapter(), "for_method_handle_call mismatch"); + CallGenerator* cg = CallGenerator::for_method_handle_inline(method_handle, jvms, caller, callee, profile); + if (cg != NULL) + return cg; + return CallGenerator::for_direct_call(callee); +} + CallGenerator* CallGenerator::for_method_handle_inline(Node* method_handle, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile) { if (method_handle->Opcode() == Op_ConP) { @@ -721,8 +732,8 @@ CallGenerator* CallGenerator::for_method_handle_inline(Node* method_handle, JVMS // Generate a guard so that each can be inlined. We might want to // do more inputs at later point but this gets the most common // case. - CallGenerator* cg1 = for_method_handle_inline(method_handle->in(1), jvms, caller, callee, profile.rescale(1.0 - prob)); - CallGenerator* cg2 = for_method_handle_inline(method_handle->in(2), jvms, caller, callee, profile.rescale(prob)); + CallGenerator* cg1 = for_method_handle_call(method_handle->in(1), jvms, caller, callee, profile.rescale(1.0 - prob)); + CallGenerator* cg2 = for_method_handle_call(method_handle->in(2), jvms, caller, callee, profile.rescale(prob)); if (cg1 != NULL && cg2 != NULL) { const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr(); ciObject* const_oop = oop_ptr->const_oop(); @@ -733,6 +744,17 @@ CallGenerator* CallGenerator::for_method_handle_inline(Node* method_handle, JVMS return NULL; } +CallGenerator* CallGenerator::for_invokedynamic_call(JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile) { + assert(callee->is_method_handle_invoke() || callee->is_method_handle_adapter(), "for_invokedynamic_call mismatch"); + // Get the CallSite object. + ciBytecodeStream str(caller); + str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci. + ciCallSite* call_site = str.get_call_site(); + CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, callee, profile); + if (cg != NULL) + return cg; + return CallGenerator::for_dynamic_call(callee); +} CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile) { @@ -819,7 +841,9 @@ JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) { kit.set_control(slow_ctl); if (!kit.stopped()) { slow_jvms = _if_missed->generate(kit.sync_jvms()); - assert(slow_jvms != NULL, "miss path must not fail to generate"); + if (kit.failing()) + return NULL; // might happen because of NodeCountInliningCutoff + assert(slow_jvms != NULL, "must be"); kit.add_exception_states_from(slow_jvms); kit.set_map(slow_jvms->map()); if (!kit.stopped()) diff --git a/src/share/vm/opto/callGenerator.hpp b/src/share/vm/opto/callGenerator.hpp index d95ba2b1cdcb0b7df870c0d97f0b43330d237afe..6247f7a7f7239e881747f061c8b212fd70d7721e 100644 --- a/src/share/vm/opto/callGenerator.hpp +++ b/src/share/vm/opto/callGenerator.hpp @@ -108,8 +108,11 @@ class CallGenerator : public ResourceObj { // How to generate vanilla out-of-line call sites: static CallGenerator* for_direct_call(ciMethod* m, bool separate_io_projs = false); // static, special - static CallGenerator* for_dynamic_call(ciMethod* m); // invokedynamic static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index); // virtual, interface + static CallGenerator* for_dynamic_call(ciMethod* m); // invokedynamic + + static CallGenerator* for_method_handle_call(Node* method_handle, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile); + static CallGenerator* for_invokedynamic_call( JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile); static CallGenerator* for_method_handle_inline(Node* method_handle, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile); static CallGenerator* for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile); diff --git a/src/share/vm/opto/doCall.cpp b/src/share/vm/opto/doCall.cpp index b3c405ff52742141063c35ccf30a73238008b976..9ff9a89f337020584078131d049c30ed91a4fdcb 100644 --- a/src/share/vm/opto/doCall.cpp +++ b/src/share/vm/opto/doCall.cpp @@ -62,7 +62,6 @@ void trace_type_profile(ciMethod *method, int depth, int bci, ciMethod *prof_met CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float prof_factor) { - CallGenerator* cg; ciMethod* caller = jvms->method(); int bci = jvms->bci(); Bytecodes::Code bytecode = caller->java_code_at_bci(bci); @@ -110,7 +109,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, // We do this before the strict f.p. check below because the // intrinsics handle strict f.p. correctly. if (allow_inline) { - cg = find_intrinsic(call_method, call_is_virtual); + CallGenerator* cg = find_intrinsic(call_method, call_is_virtual); if (cg != NULL) return cg; } @@ -121,33 +120,16 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, if (call_method->is_method_handle_invoke()) { if (bytecode != Bytecodes::_invokedynamic) { GraphKit kit(jvms); - Node* n = kit.argument(0); - - CallGenerator* cg = CallGenerator::for_method_handle_inline(n, jvms, caller, call_method, profile); - if (cg != NULL) { - return cg; - } - return CallGenerator::for_direct_call(call_method); + Node* method_handle = kit.argument(0); + return CallGenerator::for_method_handle_call(method_handle, jvms, caller, call_method, profile); } else { - // Get the CallSite object. - ciMethod* caller_method = jvms->method(); - ciBytecodeStream str(caller_method); - str.force_bci(jvms->bci()); // Set the stream to the invokedynamic bci. - ciCallSite* call_site = str.get_call_site(); - - CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, call_method, profile); - if (cg != NULL) { - return cg; - } - // If something failed, generate a normal dynamic call. - return CallGenerator::for_dynamic_call(call_method); + return CallGenerator::for_invokedynamic_call(jvms, caller, call_method, profile); } } // Do not inline strict fp into non-strict code, or the reverse - bool caller_method_is_strict = jvms->method()->is_strict(); - if( caller_method_is_strict ^ call_method->is_strict() ) { + if (caller->is_strict() ^ call_method->is_strict()) { allow_inline = false; } @@ -258,7 +240,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, } if (miss_cg != NULL) { NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count)); - cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0)); + CallGenerator* cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0)); if (cg != NULL) return cg; } }