Mercurial > hg > truffle
diff src/share/vm/interpreter/interpreterRuntime.cpp @ 6266:1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
6984705: JSR 292 method handle creation should not go through JNI
Summary: remove assembly code for JDK 7 chained method handles
Reviewed-by: jrose, twisti, kvn, mhaupt
Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>
author | twisti |
---|---|
date | Tue, 24 Jul 2012 10:51:00 -0700 |
parents | dd785aabe02b |
children | 957c266d8bc5 da91efe96a93 |
line wrap: on
line diff
--- a/src/share/vm/interpreter/interpreterRuntime.cpp Mon Jul 23 13:04:59 2012 -0700 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Tue Jul 24 10:51:00 2012 -0700 @@ -145,7 +145,7 @@ // The bytecode wrappers aren't GC-safe so construct a new one Bytecode_loadconstant ldc2(m, bci(thread)); ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc2.cache_index()); - assert(result == cpce->f1(), "expected result for assembly code"); + assert(result == cpce->f1_as_instance(), "expected result for assembly code"); } #endif } @@ -656,7 +656,7 @@ JvmtiExport::post_raw_breakpoint(thread, method, bcp); IRT_END -IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) +IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) { // extract receiver from the outgoing argument list if necessary Handle receiver(thread, NULL); if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { @@ -724,86 +724,54 @@ info.resolved_method(), info.vtable_index()); } +} +IRT_END + + +// First time execution: Resolve symbols, create a permanent MethodType object. +IRT_ENTRY(void, InterpreterRuntime::resolve_invokehandle(JavaThread* thread)) { + assert(EnableInvokeDynamic, ""); + const Bytecodes::Code bytecode = Bytecodes::_invokehandle; + + // resolve method + CallInfo info; + constantPoolHandle pool(thread, method(thread)->constants()); + + { + JvmtiHideSingleStepping jhss(thread); + LinkResolver::resolve_invoke(info, Handle(), pool, + get_index_u2_cpcache(thread, bytecode), bytecode, CHECK); + } // end JvmtiHideSingleStepping + + cache_entry(thread)->set_method_handle( + info.resolved_method(), + info.resolved_appendix()); +} IRT_END // First time execution: Resolve symbols, create a permanent CallSite object. IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) { - ResourceMark rm(thread); - assert(EnableInvokeDynamic, ""); - const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; - methodHandle caller_method(thread, method(thread)); - - constantPoolHandle pool(thread, caller_method->constants()); - pool->set_invokedynamic(); // mark header to flag active call sites + //TO DO: consider passing BCI to Java. + // int caller_bci = method(thread)->bci_from(bcp(thread)); - int caller_bci = 0; - int site_index = 0; - { address caller_bcp = bcp(thread); - caller_bci = caller_method->bci_from(caller_bcp); - site_index = Bytes::get_native_u4(caller_bcp+1); - } - assert(site_index == InterpreterRuntime::bytecode(thread).get_index_u4(bytecode), ""); - assert(constantPoolCacheOopDesc::is_secondary_index(site_index), "proper format"); - // there is a second CPC entries that is of interest; it caches signature info: - int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index(); - int pool_index = pool->cache()->entry_at(main_index)->constant_pool_index(); - - // first resolve the signature to a MH.invoke methodOop - if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) { - JvmtiHideSingleStepping jhss(thread); - CallInfo callinfo; - LinkResolver::resolve_invoke(callinfo, Handle(), pool, - site_index, bytecode, CHECK); - // The main entry corresponds to a JVM_CONSTANT_InvokeDynamic, and serves - // as a common reference point for all invokedynamic call sites with - // that exact call descriptor. We will link it in the CP cache exactly - // as if it were an invokevirtual of MethodHandle.invoke. - pool->cache()->entry_at(main_index)->set_method( - bytecode, - callinfo.resolved_method(), - callinfo.vtable_index()); - } + // resolve method + CallInfo info; + constantPoolHandle pool(thread, method(thread)->constants()); + int index = get_index_u4(thread, bytecode); - // The method (f2 entry) of the main entry is the MH.invoke for the - // invokedynamic target call signature. - oop f1_value = pool->cache()->entry_at(main_index)->f1(); - methodHandle signature_invoker(THREAD, (methodOop) f1_value); - assert(signature_invoker.not_null() && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), - "correct result from LinkResolver::resolve_invokedynamic"); - - Handle info; // optional argument(s) in JVM_CONSTANT_InvokeDynamic - Handle bootm = SystemDictionary::find_bootstrap_method(caller_method, caller_bci, - main_index, info, CHECK); - if (!java_lang_invoke_MethodHandle::is_instance(bootm())) { - THROW_MSG(vmSymbols::java_lang_IllegalStateException(), - "no bootstrap method found for invokedynamic"); - } + { + JvmtiHideSingleStepping jhss(thread); + LinkResolver::resolve_invoke(info, Handle(), pool, + index, bytecode, CHECK); + } // end JvmtiHideSingleStepping - // Short circuit if CallSite has been bound already: - if (!pool->cache()->secondary_entry_at(site_index)->is_f1_null()) - return; - - Symbol* call_site_name = pool->name_ref_at(site_index); - - Handle call_site - = SystemDictionary::make_dynamic_call_site(bootm, - // Callee information: - call_site_name, - signature_invoker, - info, - // Caller information: - caller_method, - caller_bci, - CHECK); - - // In the secondary entry, the f1 field is the call site, and the f2 (index) - // field is some data about the invoke site. Currently, it is just the BCI. - // Later, it might be changed to help manage inlining dependencies. - pool->cache()->secondary_entry_at(site_index)->set_dynamic_call(call_site, signature_invoker); + pool->cache()->secondary_entry_at(index)->set_dynamic_call( + info.resolved_method(), + info.resolved_appendix()); } IRT_END @@ -975,7 +943,7 @@ // check the access_flags for the field in the klass - instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1())); + instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror())); int index = cp_entry->field_index(); if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return; @@ -998,15 +966,15 @@ // non-static field accessors have an object, but we need a handle h_obj = Handle(thread, obj); } - instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1())); - jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2(), is_static); + instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror())); + jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2_as_index(), is_static); JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid); IRT_END IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value)) - klassOop k = java_lang_Class::as_klassOop(cp_entry->f1()); + klassOop k = java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror()); // check the access_flags for the field in the klass instanceKlass* ik = instanceKlass::cast(k); @@ -1031,7 +999,7 @@ HandleMark hm(thread); instanceKlassHandle h_klass(thread, k); - jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2(), is_static); + jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2_as_index(), is_static); jvalue fvalue; #ifdef _LP64 fvalue = *value;