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:
Christian Thalinger 2012-07-24 10:51:00 -07:00
parent 893817c28d
commit 12901d0e5b
181 changed files with 5760 additions and 14402 deletions

View file

@ -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();
}
// ------------------------------------------------------------------