mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-22 03:54:33 +02:00
7023639: JSR 292 method handle invocation needs a fast path for compiled code
6984705: JSR 292 method handle creation should not go through JNI Remove assembly code for JDK 7 chained method handles Co-authored-by: John Rose <john.r.rose@oracle.com> Co-authored-by: Michael Haupt <michael.haupt@oracle.com> Reviewed-by: jrose, twisti, kvn, mhaupt
This commit is contained in:
parent
893817c28d
commit
12901d0e5b
181 changed files with 5760 additions and 14402 deletions
|
@ -50,7 +50,6 @@
|
|||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/oop.inline2.hpp"
|
||||
#include "prims/jvmtiExport.hpp"
|
||||
#include "prims/methodHandleWalk.hpp"
|
||||
#include "runtime/init.hpp"
|
||||
#include "runtime/reflection.hpp"
|
||||
#include "runtime/sharedRuntime.hpp"
|
||||
|
@ -582,7 +581,7 @@ ciConstant ciEnv::get_constant_by_index_impl(constantPoolHandle cpool,
|
|||
assert(index < 0, "only one kind of index at a time");
|
||||
ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index);
|
||||
index = cpc_entry->constant_pool_index();
|
||||
oop obj = cpc_entry->f1();
|
||||
oop obj = cpc_entry->f1_as_instance();
|
||||
if (obj != NULL) {
|
||||
assert(obj->is_instance() || obj->is_array(), "must be a Java reference");
|
||||
ciObject* ciobj = get_object(obj);
|
||||
|
@ -750,7 +749,7 @@ ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
|
|||
|
||||
if (cpool->has_preresolution()
|
||||
|| (holder == ciEnv::MethodHandle_klass() &&
|
||||
methodOopDesc::is_method_handle_invoke_name(name_sym))) {
|
||||
MethodHandles::is_signature_polymorphic_name(holder->get_klassOop(), name_sym))) {
|
||||
// Short-circuit lookups for JSR 292-related call sites.
|
||||
// That is, do not rely only on name-based lookups, because they may fail
|
||||
// if the names are not resolvable in the boot class loader (7056328).
|
||||
|
@ -760,11 +759,13 @@ ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
|
|||
case Bytecodes::_invokespecial:
|
||||
case Bytecodes::_invokestatic:
|
||||
{
|
||||
methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index, bc);
|
||||
oop appendix_oop = NULL;
|
||||
methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index);
|
||||
if (m != NULL) {
|
||||
return get_object(m)->as_method();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -800,27 +801,28 @@ ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
|
|||
// Compare the following logic with InterpreterRuntime::resolve_invokedynamic.
|
||||
assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic");
|
||||
|
||||
bool is_resolved = cpool->cache()->main_entry_at(index)->is_resolved(bc);
|
||||
if (is_resolved && cpool->cache()->secondary_entry_at(index)->is_f1_null())
|
||||
// FIXME: code generation could allow for null (unlinked) call site
|
||||
is_resolved = false;
|
||||
ConstantPoolCacheEntry* secondary_entry = cpool->cache()->secondary_entry_at(index);
|
||||
bool is_resolved = !secondary_entry->is_f1_null();
|
||||
// FIXME: code generation could allow for null (unlinked) call site
|
||||
// The call site could be made patchable as follows:
|
||||
// Load the appendix argument from the constant pool.
|
||||
// Test the appendix argument and jump to a known deopt routine if it is null.
|
||||
// Jump through a patchable call site, which is initially a deopt routine.
|
||||
// Patch the call site to the nmethod entry point of the static compiled lambda form.
|
||||
// As with other two-component call sites, both values must be independently verified.
|
||||
|
||||
// Call site might not be resolved yet. We could create a real invoker method from the
|
||||
// compiler, but it is simpler to stop the code path here with an unlinked method.
|
||||
// Call site might not be resolved yet.
|
||||
// Stop the code path here with an unlinked method.
|
||||
if (!is_resolved) {
|
||||
ciInstanceKlass* holder = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
|
||||
ciSymbol* name = ciSymbol::invokeExact_name();
|
||||
ciSymbol* name = ciSymbol::invokeBasic_name();
|
||||
ciSymbol* signature = get_symbol(cpool->signature_ref_at(index));
|
||||
return get_unloaded_method(holder, name, signature, accessor);
|
||||
}
|
||||
|
||||
// Get the invoker methodOop from the constant pool.
|
||||
oop f1_value = cpool->cache()->main_entry_at(index)->f1();
|
||||
methodOop signature_invoker = (methodOop) f1_value;
|
||||
assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(),
|
||||
"correct result from LinkResolver::resolve_invokedynamic");
|
||||
|
||||
return get_object(signature_invoker)->as_method();
|
||||
// Get the invoker methodOop and the extra argument from the constant pool.
|
||||
methodOop adapter = secondary_entry->f2_as_vfinal_method();
|
||||
return get_object(adapter)->as_method();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1131,7 +1133,7 @@ uint ciEnv::compile_id() {
|
|||
// ------------------------------------------------------------------
|
||||
// ciEnv::notice_inlined_method()
|
||||
void ciEnv::notice_inlined_method(ciMethod* method) {
|
||||
_num_inlined_bytecodes += method->code_size();
|
||||
_num_inlined_bytecodes += method->code_size_for_inlining();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue