mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
6893268: additional dynamic language related optimizations in C2
C2 needs some additional optimizations to be able to handle MethodHandle invokes and invokedynamic instructions at the best performance. Reviewed-by: kvn, never
This commit is contained in:
parent
375527d84e
commit
47f2433a58
52 changed files with 1781 additions and 342 deletions
|
@ -224,16 +224,61 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
|
|||
}
|
||||
}
|
||||
|
||||
// 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 if (call_method->is_method_handle_invoke()) {
|
||||
if (jvms->method()->java_code_at_bci(jvms->bci()) == Bytecodes::_invokedynamic)
|
||||
return CallGenerator::for_dynamic_call(call_method);
|
||||
else
|
||||
// %%% if the target MH is a compile-time constant, we should try to inline it
|
||||
return CallGenerator::for_direct_call(call_method);
|
||||
} else {
|
||||
// Class Hierarchy Analysis or Type Profile reveals a unique target,
|
||||
// or it is a static or special call.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue