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