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 |