# HG changeset patch # User twisti # Date 1321531650 28800 # Node ID a04a201f0f5a5eb55a8f2aafc51a943fbf73d786 # Parent 973293defacd340fa4ece8bcd22f4e069fd9bc12 7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not Reviewed-by: kvn, never diff -r 973293defacd -r a04a201f0f5a src/share/vm/ci/ciMethod.hpp --- a/src/share/vm/ci/ciMethod.hpp Wed Nov 16 19:42:58 2011 -0800 +++ b/src/share/vm/ci/ciMethod.hpp Thu Nov 17 04:07:30 2011 -0800 @@ -295,12 +295,6 @@ // 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 -r 973293defacd -r a04a201f0f5a src/share/vm/opto/callGenerator.cpp --- a/src/share/vm/opto/callGenerator.cpp Wed Nov 16 19:42:58 2011 -0800 +++ b/src/share/vm/opto/callGenerator.cpp Thu Nov 17 04:07:30 2011 -0800 @@ -318,17 +318,17 @@ 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 @@ 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_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 @@ // 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 @@ 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 @@ 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 -r 973293defacd -r a04a201f0f5a src/share/vm/opto/callGenerator.hpp --- a/src/share/vm/opto/callGenerator.hpp Wed Nov 16 19:42:58 2011 -0800 +++ b/src/share/vm/opto/callGenerator.hpp Thu Nov 17 04:07:30 2011 -0800 @@ -108,8 +108,11 @@ // 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_virtual_call(ciMethod* m, int vtable_index); // virtual, interface static CallGenerator* for_dynamic_call(ciMethod* m); // invokedynamic - static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index); // virtual, interface + + 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 -r 973293defacd -r a04a201f0f5a src/share/vm/opto/doCall.cpp --- a/src/share/vm/opto/doCall.cpp Wed Nov 16 19:42:58 2011 -0800 +++ b/src/share/vm/opto/doCall.cpp Thu Nov 17 04:07:30 2011 -0800 @@ -62,7 +62,6 @@ 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 @@ // 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 @@ 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 @@ } 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; } }