comparison 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
comparison
equal deleted inserted replaced
6241:aba91a731143 6266:1d7922586cf6
143 #ifdef ASSERT 143 #ifdef ASSERT
144 { 144 {
145 // The bytecode wrappers aren't GC-safe so construct a new one 145 // The bytecode wrappers aren't GC-safe so construct a new one
146 Bytecode_loadconstant ldc2(m, bci(thread)); 146 Bytecode_loadconstant ldc2(m, bci(thread));
147 ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc2.cache_index()); 147 ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc2.cache_index());
148 assert(result == cpce->f1(), "expected result for assembly code"); 148 assert(result == cpce->f1_as_instance(), "expected result for assembly code");
149 } 149 }
150 #endif 150 #endif
151 } 151 }
152 IRT_END 152 IRT_END
153 153
654 654
655 IRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, methodOopDesc* method, address bcp)) 655 IRT_ENTRY(void, InterpreterRuntime::_breakpoint(JavaThread* thread, methodOopDesc* method, address bcp))
656 JvmtiExport::post_raw_breakpoint(thread, method, bcp); 656 JvmtiExport::post_raw_breakpoint(thread, method, bcp);
657 IRT_END 657 IRT_END
658 658
659 IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) 659 IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) {
660 // extract receiver from the outgoing argument list if necessary 660 // extract receiver from the outgoing argument list if necessary
661 Handle receiver(thread, NULL); 661 Handle receiver(thread, NULL);
662 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) { 662 if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
663 ResourceMark rm(thread); 663 ResourceMark rm(thread);
664 methodHandle m (thread, method(thread)); 664 methodHandle m (thread, method(thread));
722 cache_entry(thread)->set_method( 722 cache_entry(thread)->set_method(
723 bytecode, 723 bytecode,
724 info.resolved_method(), 724 info.resolved_method(),
725 info.vtable_index()); 725 info.vtable_index());
726 } 726 }
727 }
728 IRT_END
729
730
731 // First time execution: Resolve symbols, create a permanent MethodType object.
732 IRT_ENTRY(void, InterpreterRuntime::resolve_invokehandle(JavaThread* thread)) {
733 assert(EnableInvokeDynamic, "");
734 const Bytecodes::Code bytecode = Bytecodes::_invokehandle;
735
736 // resolve method
737 CallInfo info;
738 constantPoolHandle pool(thread, method(thread)->constants());
739
740 {
741 JvmtiHideSingleStepping jhss(thread);
742 LinkResolver::resolve_invoke(info, Handle(), pool,
743 get_index_u2_cpcache(thread, bytecode), bytecode, CHECK);
744 } // end JvmtiHideSingleStepping
745
746 cache_entry(thread)->set_method_handle(
747 info.resolved_method(),
748 info.resolved_appendix());
749 }
727 IRT_END 750 IRT_END
728 751
729 752
730 // First time execution: Resolve symbols, create a permanent CallSite object. 753 // First time execution: Resolve symbols, create a permanent CallSite object.
731 IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) { 754 IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
732 ResourceMark rm(thread);
733
734 assert(EnableInvokeDynamic, ""); 755 assert(EnableInvokeDynamic, "");
735
736 const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; 756 const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
737 757
738 methodHandle caller_method(thread, method(thread)); 758 //TO DO: consider passing BCI to Java.
739 759 // int caller_bci = method(thread)->bci_from(bcp(thread));
740 constantPoolHandle pool(thread, caller_method->constants()); 760
741 pool->set_invokedynamic(); // mark header to flag active call sites 761 // resolve method
742 762 CallInfo info;
743 int caller_bci = 0; 763 constantPoolHandle pool(thread, method(thread)->constants());
744 int site_index = 0; 764 int index = get_index_u4(thread, bytecode);
745 { address caller_bcp = bcp(thread); 765
746 caller_bci = caller_method->bci_from(caller_bcp); 766 {
747 site_index = Bytes::get_native_u4(caller_bcp+1);
748 }
749 assert(site_index == InterpreterRuntime::bytecode(thread).get_index_u4(bytecode), "");
750 assert(constantPoolCacheOopDesc::is_secondary_index(site_index), "proper format");
751 // there is a second CPC entries that is of interest; it caches signature info:
752 int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index();
753 int pool_index = pool->cache()->entry_at(main_index)->constant_pool_index();
754
755 // first resolve the signature to a MH.invoke methodOop
756 if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) {
757 JvmtiHideSingleStepping jhss(thread); 767 JvmtiHideSingleStepping jhss(thread);
758 CallInfo callinfo; 768 LinkResolver::resolve_invoke(info, Handle(), pool,
759 LinkResolver::resolve_invoke(callinfo, Handle(), pool, 769 index, bytecode, CHECK);
760 site_index, bytecode, CHECK); 770 } // end JvmtiHideSingleStepping
761 // The main entry corresponds to a JVM_CONSTANT_InvokeDynamic, and serves 771
762 // as a common reference point for all invokedynamic call sites with 772 pool->cache()->secondary_entry_at(index)->set_dynamic_call(
763 // that exact call descriptor. We will link it in the CP cache exactly 773 info.resolved_method(),
764 // as if it were an invokevirtual of MethodHandle.invoke. 774 info.resolved_appendix());
765 pool->cache()->entry_at(main_index)->set_method(
766 bytecode,
767 callinfo.resolved_method(),
768 callinfo.vtable_index());
769 }
770
771 // The method (f2 entry) of the main entry is the MH.invoke for the
772 // invokedynamic target call signature.
773 oop f1_value = pool->cache()->entry_at(main_index)->f1();
774 methodHandle signature_invoker(THREAD, (methodOop) f1_value);
775 assert(signature_invoker.not_null() && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(),
776 "correct result from LinkResolver::resolve_invokedynamic");
777
778 Handle info; // optional argument(s) in JVM_CONSTANT_InvokeDynamic
779 Handle bootm = SystemDictionary::find_bootstrap_method(caller_method, caller_bci,
780 main_index, info, CHECK);
781 if (!java_lang_invoke_MethodHandle::is_instance(bootm())) {
782 THROW_MSG(vmSymbols::java_lang_IllegalStateException(),
783 "no bootstrap method found for invokedynamic");
784 }
785
786 // Short circuit if CallSite has been bound already:
787 if (!pool->cache()->secondary_entry_at(site_index)->is_f1_null())
788 return;
789
790 Symbol* call_site_name = pool->name_ref_at(site_index);
791
792 Handle call_site
793 = SystemDictionary::make_dynamic_call_site(bootm,
794 // Callee information:
795 call_site_name,
796 signature_invoker,
797 info,
798 // Caller information:
799 caller_method,
800 caller_bci,
801 CHECK);
802
803 // In the secondary entry, the f1 field is the call site, and the f2 (index)
804 // field is some data about the invoke site. Currently, it is just the BCI.
805 // Later, it might be changed to help manage inlining dependencies.
806 pool->cache()->secondary_entry_at(site_index)->set_dynamic_call(call_site, signature_invoker);
807 } 775 }
808 IRT_END 776 IRT_END
809 777
810 778
811 //------------------------------------------------------------------------------------------------------------------------ 779 //------------------------------------------------------------------------------------------------------------------------
973 IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj, 941 IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj,
974 ConstantPoolCacheEntry *cp_entry)) 942 ConstantPoolCacheEntry *cp_entry))
975 943
976 // check the access_flags for the field in the klass 944 // check the access_flags for the field in the klass
977 945
978 instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1())); 946 instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror()));
979 int index = cp_entry->field_index(); 947 int index = cp_entry->field_index();
980 if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return; 948 if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return;
981 949
982 switch(cp_entry->flag_state()) { 950 switch(cp_entry->flag_state()) {
983 case btos: // fall through 951 case btos: // fall through
996 Handle h_obj; 964 Handle h_obj;
997 if (!is_static) { 965 if (!is_static) {
998 // non-static field accessors have an object, but we need a handle 966 // non-static field accessors have an object, but we need a handle
999 h_obj = Handle(thread, obj); 967 h_obj = Handle(thread, obj);
1000 } 968 }
1001 instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1())); 969 instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror()));
1002 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2(), is_static); 970 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2_as_index(), is_static);
1003 JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid); 971 JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid);
1004 IRT_END 972 IRT_END
1005 973
1006 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread, 974 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
1007 oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value)) 975 oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value))
1008 976
1009 klassOop k = java_lang_Class::as_klassOop(cp_entry->f1()); 977 klassOop k = java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror());
1010 978
1011 // check the access_flags for the field in the klass 979 // check the access_flags for the field in the klass
1012 instanceKlass* ik = instanceKlass::cast(k); 980 instanceKlass* ik = instanceKlass::cast(k);
1013 int index = cp_entry->field_index(); 981 int index = cp_entry->field_index();
1014 // bail out if field modifications are not watched 982 // bail out if field modifications are not watched
1029 } 997 }
1030 bool is_static = (obj == NULL); 998 bool is_static = (obj == NULL);
1031 999
1032 HandleMark hm(thread); 1000 HandleMark hm(thread);
1033 instanceKlassHandle h_klass(thread, k); 1001 instanceKlassHandle h_klass(thread, k);
1034 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2(), is_static); 1002 jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2_as_index(), is_static);
1035 jvalue fvalue; 1003 jvalue fvalue;
1036 #ifdef _LP64 1004 #ifdef _LP64
1037 fvalue = *value; 1005 fvalue = *value;
1038 #else 1006 #else
1039 // Long/double values are stored unaligned and also noncontiguously with 1007 // Long/double values are stored unaligned and also noncontiguously with