Mercurial > hg > truffle
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 |