Mercurial > hg > truffle
comparison src/share/vm/ci/ciEnv.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 | 5eb9169b1a14 |
children | 957c266d8bc5 7f813940ac35 |
comparison
equal
deleted
inserted
replaced
6241:aba91a731143 | 6266:1d7922586cf6 |
---|---|
48 #include "oops/methodDataOop.hpp" | 48 #include "oops/methodDataOop.hpp" |
49 #include "oops/objArrayKlass.hpp" | 49 #include "oops/objArrayKlass.hpp" |
50 #include "oops/oop.inline.hpp" | 50 #include "oops/oop.inline.hpp" |
51 #include "oops/oop.inline2.hpp" | 51 #include "oops/oop.inline2.hpp" |
52 #include "prims/jvmtiExport.hpp" | 52 #include "prims/jvmtiExport.hpp" |
53 #include "prims/methodHandleWalk.hpp" | |
54 #include "runtime/init.hpp" | 53 #include "runtime/init.hpp" |
55 #include "runtime/reflection.hpp" | 54 #include "runtime/reflection.hpp" |
56 #include "runtime/sharedRuntime.hpp" | 55 #include "runtime/sharedRuntime.hpp" |
57 #include "utilities/dtrace.hpp" | 56 #include "utilities/dtrace.hpp" |
58 #ifdef COMPILER1 | 57 #ifdef COMPILER1 |
580 int index = pool_index; | 579 int index = pool_index; |
581 if (cache_index >= 0) { | 580 if (cache_index >= 0) { |
582 assert(index < 0, "only one kind of index at a time"); | 581 assert(index < 0, "only one kind of index at a time"); |
583 ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index); | 582 ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index); |
584 index = cpc_entry->constant_pool_index(); | 583 index = cpc_entry->constant_pool_index(); |
585 oop obj = cpc_entry->f1(); | 584 oop obj = cpc_entry->f1_as_instance(); |
586 if (obj != NULL) { | 585 if (obj != NULL) { |
587 assert(obj->is_instance() || obj->is_array(), "must be a Java reference"); | 586 assert(obj->is_instance() || obj->is_array(), "must be a Java reference"); |
588 ciObject* ciobj = get_object(obj); | 587 ciObject* ciobj = get_object(obj); |
589 return ciConstant(T_OBJECT, ciobj); | 588 return ciConstant(T_OBJECT, ciobj); |
590 } | 589 } |
748 Symbol* name_sym = cpool->name_ref_at(index); | 747 Symbol* name_sym = cpool->name_ref_at(index); |
749 Symbol* sig_sym = cpool->signature_ref_at(index); | 748 Symbol* sig_sym = cpool->signature_ref_at(index); |
750 | 749 |
751 if (cpool->has_preresolution() | 750 if (cpool->has_preresolution() |
752 || (holder == ciEnv::MethodHandle_klass() && | 751 || (holder == ciEnv::MethodHandle_klass() && |
753 methodOopDesc::is_method_handle_invoke_name(name_sym))) { | 752 MethodHandles::is_signature_polymorphic_name(holder->get_klassOop(), name_sym))) { |
754 // Short-circuit lookups for JSR 292-related call sites. | 753 // Short-circuit lookups for JSR 292-related call sites. |
755 // That is, do not rely only on name-based lookups, because they may fail | 754 // That is, do not rely only on name-based lookups, because they may fail |
756 // if the names are not resolvable in the boot class loader (7056328). | 755 // if the names are not resolvable in the boot class loader (7056328). |
757 switch (bc) { | 756 switch (bc) { |
758 case Bytecodes::_invokevirtual: | 757 case Bytecodes::_invokevirtual: |
759 case Bytecodes::_invokeinterface: | 758 case Bytecodes::_invokeinterface: |
760 case Bytecodes::_invokespecial: | 759 case Bytecodes::_invokespecial: |
761 case Bytecodes::_invokestatic: | 760 case Bytecodes::_invokestatic: |
762 { | 761 { |
763 methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index, bc); | 762 oop appendix_oop = NULL; |
763 methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index); | |
764 if (m != NULL) { | 764 if (m != NULL) { |
765 return get_object(m)->as_method(); | 765 return get_object(m)->as_method(); |
766 } | 766 } |
767 } | 767 } |
768 break; | |
768 } | 769 } |
769 } | 770 } |
770 | 771 |
771 if (holder_is_accessible) { // Our declared holder is loaded. | 772 if (holder_is_accessible) { // Our declared holder is loaded. |
772 instanceKlass* lookup = declared_holder->get_instanceKlass(); | 773 instanceKlass* lookup = declared_holder->get_instanceKlass(); |
798 int index, Bytecodes::Code bc, | 799 int index, Bytecodes::Code bc, |
799 ciInstanceKlass* accessor) { | 800 ciInstanceKlass* accessor) { |
800 // Compare the following logic with InterpreterRuntime::resolve_invokedynamic. | 801 // Compare the following logic with InterpreterRuntime::resolve_invokedynamic. |
801 assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic"); | 802 assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic"); |
802 | 803 |
803 bool is_resolved = cpool->cache()->main_entry_at(index)->is_resolved(bc); | 804 ConstantPoolCacheEntry* secondary_entry = cpool->cache()->secondary_entry_at(index); |
804 if (is_resolved && cpool->cache()->secondary_entry_at(index)->is_f1_null()) | 805 bool is_resolved = !secondary_entry->is_f1_null(); |
805 // FIXME: code generation could allow for null (unlinked) call site | 806 // FIXME: code generation could allow for null (unlinked) call site |
806 is_resolved = false; | 807 // The call site could be made patchable as follows: |
807 | 808 // Load the appendix argument from the constant pool. |
808 // Call site might not be resolved yet. We could create a real invoker method from the | 809 // Test the appendix argument and jump to a known deopt routine if it is null. |
809 // compiler, but it is simpler to stop the code path here with an unlinked method. | 810 // Jump through a patchable call site, which is initially a deopt routine. |
811 // Patch the call site to the nmethod entry point of the static compiled lambda form. | |
812 // As with other two-component call sites, both values must be independently verified. | |
813 | |
814 // Call site might not be resolved yet. | |
815 // Stop the code path here with an unlinked method. | |
810 if (!is_resolved) { | 816 if (!is_resolved) { |
811 ciInstanceKlass* holder = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); | 817 ciInstanceKlass* holder = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); |
812 ciSymbol* name = ciSymbol::invokeExact_name(); | 818 ciSymbol* name = ciSymbol::invokeBasic_name(); |
813 ciSymbol* signature = get_symbol(cpool->signature_ref_at(index)); | 819 ciSymbol* signature = get_symbol(cpool->signature_ref_at(index)); |
814 return get_unloaded_method(holder, name, signature, accessor); | 820 return get_unloaded_method(holder, name, signature, accessor); |
815 } | 821 } |
816 | 822 |
817 // Get the invoker methodOop from the constant pool. | 823 // Get the invoker methodOop and the extra argument from the constant pool. |
818 oop f1_value = cpool->cache()->main_entry_at(index)->f1(); | 824 methodOop adapter = secondary_entry->f2_as_vfinal_method(); |
819 methodOop signature_invoker = (methodOop) f1_value; | 825 return get_object(adapter)->as_method(); |
820 assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), | |
821 "correct result from LinkResolver::resolve_invokedynamic"); | |
822 | |
823 return get_object(signature_invoker)->as_method(); | |
824 } | 826 } |
825 | 827 |
826 | 828 |
827 // ------------------------------------------------------------------ | 829 // ------------------------------------------------------------------ |
828 // ciEnv::get_instance_klass_for_declared_method_holder | 830 // ciEnv::get_instance_klass_for_declared_method_holder |
1129 } | 1131 } |
1130 | 1132 |
1131 // ------------------------------------------------------------------ | 1133 // ------------------------------------------------------------------ |
1132 // ciEnv::notice_inlined_method() | 1134 // ciEnv::notice_inlined_method() |
1133 void ciEnv::notice_inlined_method(ciMethod* method) { | 1135 void ciEnv::notice_inlined_method(ciMethod* method) { |
1134 _num_inlined_bytecodes += method->code_size(); | 1136 _num_inlined_bytecodes += method->code_size_for_inlining(); |
1135 } | 1137 } |
1136 | 1138 |
1137 // ------------------------------------------------------------------ | 1139 // ------------------------------------------------------------------ |
1138 // ciEnv::num_inlined_bytecodes() | 1140 // ciEnv::num_inlined_bytecodes() |
1139 int ciEnv::num_inlined_bytecodes() const { | 1141 int ciEnv::num_inlined_bytecodes() const { |