comparison src/share/vm/ci/ciEnv.cpp @ 6634:7f813940ac35

7192406: JSR 292: C2 needs exact return type information for invokedynamic and invokehandle call sites Reviewed-by: kvn
author twisti
date Tue, 28 Aug 2012 15:24:39 -0700
parents 1d7922586cf6
children c38f13903fdf da91efe96a93
comparison
equal deleted inserted replaced
6633:a5dd6e3ef9f3 6634:7f813940ac35
736 // ------------------------------------------------------------------ 736 // ------------------------------------------------------------------
737 // ciEnv::get_method_by_index_impl 737 // ciEnv::get_method_by_index_impl
738 ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool, 738 ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
739 int index, Bytecodes::Code bc, 739 int index, Bytecodes::Code bc,
740 ciInstanceKlass* accessor) { 740 ciInstanceKlass* accessor) {
741 int holder_index = cpool->klass_ref_index_at(index); 741 if (bc == Bytecodes::_invokedynamic) {
742 bool holder_is_accessible; 742 ConstantPoolCacheEntry* secondary_entry = cpool->cache()->secondary_entry_at(index);
743 ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor); 743 const bool is_resolved = !secondary_entry->is_f1_null();
744 ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder); 744 // FIXME: code generation could allow for null (unlinked) call site
745 745 // The call site could be made patchable as follows:
746 // Get the method's name and signature. 746 // Load the appendix argument from the constant pool.
747 Symbol* name_sym = cpool->name_ref_at(index); 747 // Test the appendix argument and jump to a known deopt routine if it is null.
748 Symbol* sig_sym = cpool->signature_ref_at(index); 748 // Jump through a patchable call site, which is initially a deopt routine.
749 749 // Patch the call site to the nmethod entry point of the static compiled lambda form.
750 if (cpool->has_preresolution() 750 // As with other two-component call sites, both values must be independently verified.
751 || (holder == ciEnv::MethodHandle_klass() && 751
752 MethodHandles::is_signature_polymorphic_name(holder->get_klassOop(), name_sym))) { 752 if (is_resolved) {
753 // Short-circuit lookups for JSR 292-related call sites. 753 // Get the invoker methodOop and the extra argument from the constant pool.
754 // That is, do not rely only on name-based lookups, because they may fail 754 methodOop adapter = secondary_entry->f2_as_vfinal_method();
755 // if the names are not resolvable in the boot class loader (7056328). 755 return get_object(adapter)->as_method();
756 switch (bc) { 756 }
757 case Bytecodes::_invokevirtual: 757
758 case Bytecodes::_invokeinterface: 758 // Fake a method that is equivalent to a declared method.
759 case Bytecodes::_invokespecial:
760 case Bytecodes::_invokestatic:
761 {
762 oop appendix_oop = NULL;
763 methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index);
764 if (m != NULL) {
765 return get_object(m)->as_method();
766 }
767 }
768 break;
769 }
770 }
771
772 if (holder_is_accessible) { // Our declared holder is loaded.
773 instanceKlass* lookup = declared_holder->get_instanceKlass();
774 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);
775 if (m != NULL &&
776 (bc == Bytecodes::_invokestatic
777 ? instanceKlass::cast(m->method_holder())->is_not_initialized()
778 : !instanceKlass::cast(m->method_holder())->is_loaded())) {
779 m = NULL;
780 }
781 if (m != NULL) {
782 // We found the method.
783 return get_object(m)->as_method();
784 }
785 }
786
787 // Either the declared holder was not loaded, or the method could
788 // not be found. Create a dummy ciMethod to represent the failed
789 // lookup.
790 ciSymbol* name = get_symbol(name_sym);
791 ciSymbol* signature = get_symbol(sig_sym);
792 return get_unloaded_method(declared_holder, name, signature, accessor);
793 }
794
795
796 // ------------------------------------------------------------------
797 // ciEnv::get_fake_invokedynamic_method_impl
798 ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
799 int index, Bytecodes::Code bc,
800 ciInstanceKlass* accessor) {
801 // Compare the following logic with InterpreterRuntime::resolve_invokedynamic.
802 assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic");
803
804 ConstantPoolCacheEntry* secondary_entry = cpool->cache()->secondary_entry_at(index);
805 bool is_resolved = !secondary_entry->is_f1_null();
806 // FIXME: code generation could allow for null (unlinked) call site
807 // The call site could be made patchable as follows:
808 // Load the appendix argument from the constant pool.
809 // Test the appendix argument and jump to a known deopt routine if it is null.
810 // Jump through a patchable call site, which is initially a deopt routine.
811 // Patch the call site to the nmethod entry point of the static compiled lambda form.
812 // As with other two-component call sites, both values must be independently verified.
813
814 // Call site might not be resolved yet.
815 // Stop the code path here with an unlinked method.
816 if (!is_resolved) {
817 ciInstanceKlass* holder = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass(); 759 ciInstanceKlass* holder = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
818 ciSymbol* name = ciSymbol::invokeBasic_name(); 760 ciSymbol* name = ciSymbol::invokeBasic_name();
819 ciSymbol* signature = get_symbol(cpool->signature_ref_at(index)); 761 ciSymbol* signature = get_symbol(cpool->signature_ref_at(index));
820 return get_unloaded_method(holder, name, signature, accessor); 762 return get_unloaded_method(holder, name, signature, accessor);
821 } 763 } else {
822 764 const int holder_index = cpool->klass_ref_index_at(index);
823 // Get the invoker methodOop and the extra argument from the constant pool. 765 bool holder_is_accessible;
824 methodOop adapter = secondary_entry->f2_as_vfinal_method(); 766 ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
825 return get_object(adapter)->as_method(); 767 ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
768
769 // Get the method's name and signature.
770 Symbol* name_sym = cpool->name_ref_at(index);
771 Symbol* sig_sym = cpool->signature_ref_at(index);
772
773 if (cpool->has_preresolution()
774 || (holder == ciEnv::MethodHandle_klass() &&
775 MethodHandles::is_signature_polymorphic_name(holder->get_klassOop(), name_sym))) {
776 // Short-circuit lookups for JSR 292-related call sites.
777 // That is, do not rely only on name-based lookups, because they may fail
778 // if the names are not resolvable in the boot class loader (7056328).
779 switch (bc) {
780 case Bytecodes::_invokevirtual:
781 case Bytecodes::_invokeinterface:
782 case Bytecodes::_invokespecial:
783 case Bytecodes::_invokestatic:
784 {
785 methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index);
786 if (m != NULL) {
787 return get_object(m)->as_method();
788 }
789 }
790 break;
791 }
792 }
793
794 if (holder_is_accessible) { // Our declared holder is loaded.
795 instanceKlass* lookup = declared_holder->get_instanceKlass();
796 methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);
797 if (m != NULL &&
798 (bc == Bytecodes::_invokestatic
799 ? instanceKlass::cast(m->method_holder())->is_not_initialized()
800 : !instanceKlass::cast(m->method_holder())->is_loaded())) {
801 m = NULL;
802 }
803 if (m != NULL) {
804 // We found the method.
805 return get_object(m)->as_method();
806 }
807 }
808
809 // Either the declared holder was not loaded, or the method could
810 // not be found. Create a dummy ciMethod to represent the failed
811 // lookup.
812 ciSymbol* name = get_symbol(name_sym);
813 ciSymbol* signature = get_symbol(sig_sym);
814 return get_unloaded_method(declared_holder, name, signature, accessor);
815 }
826 } 816 }
827 817
828 818
829 // ------------------------------------------------------------------ 819 // ------------------------------------------------------------------
830 // ciEnv::get_instance_klass_for_declared_method_holder 820 // ciEnv::get_instance_klass_for_declared_method_holder
851 // ------------------------------------------------------------------ 841 // ------------------------------------------------------------------
852 // ciEnv::get_method_by_index 842 // ciEnv::get_method_by_index
853 ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool, 843 ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool,
854 int index, Bytecodes::Code bc, 844 int index, Bytecodes::Code bc,
855 ciInstanceKlass* accessor) { 845 ciInstanceKlass* accessor) {
856 if (bc == Bytecodes::_invokedynamic) { 846 GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);)
857 GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc, accessor);)
858 } else {
859 GUARDED_VM_ENTRY(return get_method_by_index_impl( cpool, index, bc, accessor);)
860 }
861 } 847 }
862 848
863 849
864 // ------------------------------------------------------------------ 850 // ------------------------------------------------------------------
865 // ciEnv::name_buffer 851 // ciEnv::name_buffer