Mercurial > hg > graal-jvmci-8
comparison src/share/vm/interpreter/interpreterRuntime.cpp @ 1059:389049f3f393
6858164: invokedynamic code needs some cleanup (post-6655638)
Summary: Fix several crashers, remove needless paths for boxed-style bootstrap method call, refactor & simplify APIs for rewriter constantPoolOop, remove sun.dyn.CallSiteImpl
Reviewed-by: kvn
author | jrose |
---|---|
date | Fri, 30 Oct 2009 16:22:59 -0700 |
parents | 8b46c4d82093 |
children | dd57230ba8fe |
comparison
equal
deleted
inserted
replaced
1058:73a726751507 | 1059:389049f3f393 |
---|---|
679 info.vtable_index()); | 679 info.vtable_index()); |
680 } | 680 } |
681 IRT_END | 681 IRT_END |
682 | 682 |
683 | 683 |
684 // First time execution: Resolve symbols, create a permanent CallSiteImpl object. | 684 // First time execution: Resolve symbols, create a permanent CallSite object. |
685 IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) { | 685 IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) { |
686 ResourceMark rm(thread); | 686 ResourceMark rm(thread); |
687 | 687 |
688 assert(EnableInvokeDynamic, ""); | 688 assert(EnableInvokeDynamic, ""); |
689 | 689 |
706 } | 706 } |
707 | 707 |
708 constantPoolHandle pool(thread, caller_method->constants()); | 708 constantPoolHandle pool(thread, caller_method->constants()); |
709 pool->set_invokedynamic(); // mark header to flag active call sites | 709 pool->set_invokedynamic(); // mark header to flag active call sites |
710 | 710 |
711 int raw_index = four_byte_index(thread); | 711 int site_index = four_byte_index(thread); |
712 assert(constantPoolCacheOopDesc::is_secondary_index(raw_index), "invokedynamic indexes marked specially"); | 712 // there is a second CPC entries that is of interest; it caches signature info: |
713 | 713 int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index(); |
714 // there are two CPC entries that are of interest: | |
715 int site_index = constantPoolCacheOopDesc::decode_secondary_index(raw_index); | |
716 int main_index = pool->cache()->entry_at(site_index)->main_entry_index(); | |
717 // and there is one CP entry, a NameAndType: | |
718 int nt_index = pool->map_instruction_operand_to_index(raw_index); | |
719 | 714 |
720 // first resolve the signature to a MH.invoke methodOop | 715 // first resolve the signature to a MH.invoke methodOop |
721 if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) { | 716 if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) { |
722 JvmtiHideSingleStepping jhss(thread); | 717 JvmtiHideSingleStepping jhss(thread); |
723 CallInfo info; | 718 CallInfo info; |
724 LinkResolver::resolve_invoke(info, Handle(), pool, | 719 LinkResolver::resolve_invoke(info, Handle(), pool, |
725 raw_index, bytecode, CHECK); | 720 site_index, bytecode, CHECK); |
726 // The main entry corresponds to a JVM_CONSTANT_NameAndType, and serves | 721 // The main entry corresponds to a JVM_CONSTANT_NameAndType, and serves |
727 // as a common reference point for all invokedynamic call sites with | 722 // as a common reference point for all invokedynamic call sites with |
728 // that exact call descriptor. We will link it in the CP cache exactly | 723 // that exact call descriptor. We will link it in the CP cache exactly |
729 // as if it were an invokevirtual of MethodHandle.invoke. | 724 // as if it were an invokevirtual of MethodHandle.invoke. |
730 pool->cache()->entry_at(main_index)->set_method( | 725 pool->cache()->entry_at(main_index)->set_method( |
739 intptr_t f2_value = pool->cache()->entry_at(main_index)->f2(); | 734 intptr_t f2_value = pool->cache()->entry_at(main_index)->f2(); |
740 methodHandle mh_invdyn(THREAD, (methodOop) f2_value); | 735 methodHandle mh_invdyn(THREAD, (methodOop) f2_value); |
741 assert(mh_invdyn.not_null() && mh_invdyn->is_method() && mh_invdyn->is_method_handle_invoke(), | 736 assert(mh_invdyn.not_null() && mh_invdyn->is_method() && mh_invdyn->is_method_handle_invoke(), |
742 "correct result from LinkResolver::resolve_invokedynamic"); | 737 "correct result from LinkResolver::resolve_invokedynamic"); |
743 | 738 |
744 symbolHandle call_site_name(THREAD, pool->nt_name_ref_at(nt_index)); | 739 symbolHandle call_site_name(THREAD, pool->name_ref_at(site_index)); |
745 Handle call_site | 740 Handle call_site |
746 = SystemDictionary::make_dynamic_call_site(caller_method->method_holder(), | 741 = SystemDictionary::make_dynamic_call_site(caller_method->method_holder(), |
747 caller_method->method_idnum(), | 742 caller_method->method_idnum(), |
748 caller_method->bci_from(bcp(thread)), | 743 caller_method->bci_from(bcp(thread)), |
749 call_site_name, | 744 call_site_name, |
751 CHECK); | 746 CHECK); |
752 | 747 |
753 // In the secondary entry, the f1 field is the call site, and the f2 (index) | 748 // In the secondary entry, the f1 field is the call site, and the f2 (index) |
754 // field is some data about the invoke site. | 749 // field is some data about the invoke site. |
755 int extra_data = 0; | 750 int extra_data = 0; |
756 pool->cache()->entry_at(site_index)->set_dynamic_call(call_site(), extra_data); | 751 pool->cache()->secondary_entry_at(site_index)->set_dynamic_call(call_site(), extra_data); |
757 } | 752 } |
758 IRT_END | 753 IRT_END |
759 | |
760 | |
761 // Called on first time execution, and also whenever the CallSite.target is null. | |
762 // FIXME: Do more of this in Java code. | |
763 IRT_ENTRY(void, InterpreterRuntime::bootstrap_invokedynamic(JavaThread* thread, oopDesc* call_site)) { | |
764 methodHandle mh_invdyn(thread, (methodOop) sun_dyn_CallSiteImpl::vmmethod(call_site)); | |
765 Handle mh_type(thread, mh_invdyn->method_handle_type()); | |
766 objArrayHandle mh_ptypes(thread, java_dyn_MethodType::ptypes(mh_type())); | |
767 | |
768 // squish the arguments down to a single array | |
769 int nargs = mh_ptypes->length(); | |
770 objArrayHandle arg_array; | |
771 { | |
772 objArrayOop aaoop = oopFactory::new_objArray(SystemDictionary::object_klass(), nargs, CHECK); | |
773 arg_array = objArrayHandle(thread, aaoop); | |
774 } | |
775 frame fr = thread->last_frame(); | |
776 assert(fr.interpreter_frame_bcp() != NULL, "sanity"); | |
777 int tos_offset = 0; | |
778 for (int i = nargs; --i >= 0; ) { | |
779 intptr_t* slot_addr = fr.interpreter_frame_tos_at(tos_offset++); | |
780 oop ptype = mh_ptypes->obj_at(i); | |
781 oop arg = NULL; | |
782 if (!java_lang_Class::is_primitive(ptype)) { | |
783 arg = *(oop*) slot_addr; | |
784 } else { | |
785 BasicType bt = java_lang_Class::primitive_type(ptype); | |
786 assert(frame::interpreter_frame_expression_stack_direction() < 0, "else reconsider this code"); | |
787 jvalue value; | |
788 Interpreter::get_jvalue_in_slot(slot_addr, bt, &value); | |
789 tos_offset += type2size[bt]-1; | |
790 arg = java_lang_boxing_object::create(bt, &value, CHECK); | |
791 // FIXME: These boxing objects are not canonicalized under | |
792 // the Java autoboxing rules. They should be... | |
793 // The best approach would be to push the arglist creation into Java. | |
794 // The JVM should use a lower-level interface to communicate argument lists. | |
795 } | |
796 arg_array->obj_at_put(i, arg); | |
797 } | |
798 | |
799 // now find the bootstrap method | |
800 oop bootstrap_mh_oop = instanceKlass::cast(fr.interpreter_frame_method()->method_holder())->bootstrap_method(); | |
801 assert(bootstrap_mh_oop != NULL, "resolve_invokedynamic ensures a BSM"); | |
802 | |
803 // return the bootstrap method and argument array via vm_result/_2 | |
804 thread->set_vm_result(bootstrap_mh_oop); | |
805 thread->set_vm_result_2(arg_array()); | |
806 } | |
807 IRT_END | |
808 | |
809 | 754 |
810 | 755 |
811 //------------------------------------------------------------------------------------------------------------------------ | 756 //------------------------------------------------------------------------------------------------------------------------ |
812 // Miscellaneous | 757 // Miscellaneous |
813 | 758 |