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 //------------------------------------------------------------------------------------------------------------------------ |
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 |