src/share/vm/opto/doCall.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/vm/opto/doCall.cpp	Tue Sep 28 15:14:46 2010
--- new/src/share/vm/opto/doCall.cpp	Tue Sep 28 15:14:46 2010

*** 92,101 **** --- 92,155 ---- if (allow_inline) { cg = find_intrinsic(call_method, call_is_virtual); if (cg != NULL) return cg; } + // Do MethodHandle calls. + // NOTE: This must happen before normal inlining logic below since + // MethodHandle.invoke* are native methods which obviously don't + // have bytecodes and so normal inlining fails. + if (call_method->is_method_handle_invoke()) { + if (jvms->method()->java_code_at_bci(jvms->bci()) != Bytecodes::_invokedynamic) { + GraphKit kit(jvms); + Node* n = kit.argument(0); + + if (n->Opcode() == Op_ConP) { + const TypeOopPtr* oop_ptr = n->bottom_type()->is_oopptr(); + ciObject* const_oop = oop_ptr->const_oop(); + ciMethodHandle* method_handle = const_oop->as_method_handle(); + + // Set the actually called method to have access to the class + // and signature in the MethodHandleCompiler. + method_handle->set_callee(call_method); + + // Get an adapter for the MethodHandle. + ciMethod* target_method = method_handle->get_method_handle_adapter(); + + CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor); + if (hit_cg != NULL && hit_cg->is_inline()) + return hit_cg; + } + + return CallGenerator::for_direct_call(call_method); + } + else { + // Get the MethodHandle from the CallSite. + 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(); + ciMethodHandle* method_handle = call_site->get_target(); + + // Set the actually called method to have access to the class + // and signature in the MethodHandleCompiler. + method_handle->set_callee(call_method); + + // Get an adapter for the MethodHandle. + ciMethod* target_method = method_handle->get_invokedynamic_adapter(); + + CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor); + if (hit_cg != NULL && hit_cg->is_inline()) { + CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method); + return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor); + } + + // If something failed, generate a normal dynamic call. + return CallGenerator::for_dynamic_call(call_method); + } + } + // 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() ) { allow_inline = false; }
*** 214,274 **** --- 268,277 ---- } } } } // Do MethodHandle calls. if (call_method->is_method_handle_invoke()) { if (jvms->method()->java_code_at_bci(jvms->bci()) != Bytecodes::_invokedynamic) { GraphKit kit(jvms); Node* n = kit.argument(0); if (n->Opcode() == Op_ConP) { const TypeOopPtr* oop_ptr = n->bottom_type()->is_oopptr(); ciObject* const_oop = oop_ptr->const_oop(); ciMethodHandle* method_handle = const_oop->as_method_handle(); // Set the actually called method to have access to the class // and signature in the MethodHandleCompiler. method_handle->set_callee(call_method); // Get an adapter for the MethodHandle. ciMethod* target_method = method_handle->get_method_handle_adapter(); CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor); if (hit_cg != NULL && hit_cg->is_inline()) return hit_cg; } return CallGenerator::for_direct_call(call_method); } else { // Get the MethodHandle from the CallSite. 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(); ciMethodHandle* method_handle = call_site->get_target(); // Set the actually called method to have access to the class // and signature in the MethodHandleCompiler. method_handle->set_callee(call_method); // Get an adapter for the MethodHandle. ciMethod* target_method = method_handle->get_invokedynamic_adapter(); CallGenerator* hit_cg = this->call_generator(target_method, vtable_index, false, jvms, true, prof_factor); if (hit_cg != NULL && hit_cg->is_inline()) { CallGenerator* miss_cg = CallGenerator::for_dynamic_call(call_method); return CallGenerator::for_predicted_dynamic_call(method_handle, miss_cg, hit_cg, prof_factor); } // If something failed, generate a normal dynamic call. return CallGenerator::for_dynamic_call(call_method); } } // There was no special inlining tactic, or it bailed out. // Use a more generic tactic, like a simple call. if (call_is_virtual) { return CallGenerator::for_virtual_call(call_method, vtable_index); } else {

src/share/vm/opto/doCall.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File