23 */
24
25 #include "precompiled.hpp"
26 #include "jvm.h"
27 #include "classfile/javaClasses.hpp"
28 #include "classfile/moduleEntry.hpp"
29 #include "classfile/packageEntry.hpp"
30 #include "classfile/stringTable.hpp"
31 #include "classfile/systemDictionary.hpp"
32 #include "classfile/verifier.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "interpreter/linkResolver.hpp"
35 #include "logging/log.hpp"
36 #include "memory/oopFactory.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/instanceKlass.hpp"
40 #include "oops/objArrayKlass.hpp"
41 #include "oops/objArrayOop.inline.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/typeArrayOop.inline.hpp"
44 #include "prims/jvmtiExport.hpp"
45 #include "runtime/arguments.hpp"
46 #include "runtime/fieldDescriptor.inline.hpp"
47 #include "runtime/handles.inline.hpp"
48 #include "runtime/javaCalls.hpp"
49 #include "runtime/reflection.hpp"
50 #include "runtime/reflectionUtils.hpp"
51 #include "runtime/signature.hpp"
52 #include "runtime/vframe.inline.hpp"
53
54 static void trace_class_resolution(const Klass* to_class) {
55 ResourceMark rm;
56 int line_number = -1;
57 const char * source_file = NULL;
58 Klass* caller = NULL;
59 JavaThread* jthread = JavaThread::current();
60 if (jthread->has_last_Java_frame()) {
61 vframeStream vfst(jthread);
62 // skip over any frames belonging to java.lang.Class
63 while (!vfst.at_end() &&
64 vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) {
65 vfst.next();
66 }
67 if (!vfst.at_end()) {
68 // this frame is a likely suspect
69 caller = vfst.method()->method_holder();
70 line_number = vfst.method()->line_number_from_bci(vfst.bci());
71 Symbol* s = vfst.method()->method_holder()->source_file_name();
72 if (s != NULL) {
765 if (!inner_is_member && ioff != 0 && ooff == 0 &&
766 cp->klass_name_at_matches(inner, ioff)) {
767 Klass* i = cp->klass_at(ioff, CHECK);
768 if (i == inner) {
769 return;
770 }
771 }
772 }
773
774 // 'inner' not declared as an inner klass in outer
775 ResourceMark rm(THREAD);
776 Exceptions::fthrow(
777 THREAD_AND_LOCATION,
778 vmSymbols::java_lang_IncompatibleClassChangeError(),
779 "%s and %s disagree on InnerClasses attribute",
780 outer->external_name(),
781 inner->external_name()
782 );
783 }
784
785 // Utility method converting a single SignatureStream element into java.lang.Class instance
786 static oop get_mirror_from_signature(const methodHandle& method,
787 SignatureStream* ss,
788 TRAPS) {
789
790
791 if (T_OBJECT == ss->type() || T_ARRAY == ss->type() || T_VALUETYPE == ss->type()) {
792 Symbol* name = ss->as_symbol(CHECK_NULL);
793 oop loader = method->method_holder()->class_loader();
794 oop protection_domain = method->method_holder()->protection_domain();
795 const Klass* k = SystemDictionary::resolve_or_fail(name,
796 Handle(THREAD, loader),
797 Handle(THREAD, protection_domain),
798 true,
799 CHECK_NULL);
800 if (log_is_enabled(Debug, class, resolve)) {
801 trace_class_resolution(k);
802 }
803 return k->java_mirror();
804 }
805
806 assert(ss->type() != T_VOID || ss->at_return_type(),
807 "T_VOID should only appear as return type");
808
809 return java_lang_Class::primitive_mirror(ss->type());
810 }
811
812 static objArrayHandle get_parameter_types(const methodHandle& method,
813 int parameter_count,
814 oop* return_type,
815 TRAPS) {
816 // Allocate array holding parameter types (java.lang.Class instances)
817 objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
818 objArrayHandle mirrors(THREAD, m);
819 int index = 0;
820 // Collect parameter types
821 ResourceMark rm(THREAD);
822 Symbol* signature = method->signature();
823 SignatureStream ss(signature);
824 while (!ss.at_return_type()) {
825 oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
826 mirrors->obj_at_put(index++, mirror);
827 ss.next();
828 }
829 assert(index == parameter_count, "invalid parameter count");
838 static objArrayHandle get_exception_types(const methodHandle& method, TRAPS) {
839 return method->resolved_checked_exceptions(THREAD);
840 }
841
842 static Handle new_type(Symbol* signature, Klass* k, TRAPS) {
843 // Basic types
844 BasicType type = vmSymbols::signature_type(signature);
845 if (type != T_OBJECT && type != T_VALUETYPE) {
846 return Handle(THREAD, Universe::java_mirror(type));
847 }
848
849 Klass* result =
850 SystemDictionary::resolve_or_fail(signature,
851 Handle(THREAD, k->class_loader()),
852 Handle(THREAD, k->protection_domain()),
853 true, CHECK_(Handle()));
854
855 if (log_is_enabled(Debug, class, resolve)) {
856 trace_class_resolution(result);
857 }
858
859 oop nt = result->java_mirror();
860 return Handle(THREAD, nt);
861 }
862
863
864 oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
865 // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
866 assert(!method()->is_initializer() ||
867 (for_constant_pool_access && method()->is_static()),
868 "should call new_constructor instead");
869 InstanceKlass* holder = method->method_holder();
870 int slot = method->method_idnum();
871
872 Symbol* signature = method->signature();
873 int parameter_count = ArgumentCount(signature).size();
874 oop return_type_oop = NULL;
875 objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL);
876 if (parameter_types.is_null() || return_type_oop == NULL) return NULL;
877
878 Handle return_type(THREAD, return_type_oop);
879
|
23 */
24
25 #include "precompiled.hpp"
26 #include "jvm.h"
27 #include "classfile/javaClasses.hpp"
28 #include "classfile/moduleEntry.hpp"
29 #include "classfile/packageEntry.hpp"
30 #include "classfile/stringTable.hpp"
31 #include "classfile/systemDictionary.hpp"
32 #include "classfile/verifier.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "interpreter/linkResolver.hpp"
35 #include "logging/log.hpp"
36 #include "memory/oopFactory.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/instanceKlass.hpp"
40 #include "oops/objArrayKlass.hpp"
41 #include "oops/objArrayOop.inline.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/valueKlass.hpp"
44 #include "oops/typeArrayOop.inline.hpp"
45 #include "prims/jvmtiExport.hpp"
46 #include "runtime/arguments.hpp"
47 #include "runtime/fieldDescriptor.inline.hpp"
48 #include "runtime/handles.inline.hpp"
49 #include "runtime/javaCalls.hpp"
50 #include "runtime/reflection.hpp"
51 #include "runtime/reflectionUtils.hpp"
52 #include "runtime/signature.hpp"
53 #include "runtime/vframe.inline.hpp"
54 #include "utilities/globalDefinitions.hpp"
55
56 static void trace_class_resolution(const Klass* to_class) {
57 ResourceMark rm;
58 int line_number = -1;
59 const char * source_file = NULL;
60 Klass* caller = NULL;
61 JavaThread* jthread = JavaThread::current();
62 if (jthread->has_last_Java_frame()) {
63 vframeStream vfst(jthread);
64 // skip over any frames belonging to java.lang.Class
65 while (!vfst.at_end() &&
66 vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) {
67 vfst.next();
68 }
69 if (!vfst.at_end()) {
70 // this frame is a likely suspect
71 caller = vfst.method()->method_holder();
72 line_number = vfst.method()->line_number_from_bci(vfst.bci());
73 Symbol* s = vfst.method()->method_holder()->source_file_name();
74 if (s != NULL) {
767 if (!inner_is_member && ioff != 0 && ooff == 0 &&
768 cp->klass_name_at_matches(inner, ioff)) {
769 Klass* i = cp->klass_at(ioff, CHECK);
770 if (i == inner) {
771 return;
772 }
773 }
774 }
775
776 // 'inner' not declared as an inner klass in outer
777 ResourceMark rm(THREAD);
778 Exceptions::fthrow(
779 THREAD_AND_LOCATION,
780 vmSymbols::java_lang_IncompatibleClassChangeError(),
781 "%s and %s disagree on InnerClasses attribute",
782 outer->external_name(),
783 inner->external_name()
784 );
785 }
786
787 // Returns Q-mirror if qtype_if_value is true and k is a ValueKlass;
788 // otherwise returns java_mirror or L-mirror for ValueKlass
789 static oop java_mirror(Klass* k, jboolean qtype_if_value) {
790 if (qtype_if_value && k->is_value()) {
791 ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(k));
792 return vk->value_mirror();
793 } else {
794 return k->java_mirror();
795 }
796 }
797
798 // Utility method converting a single SignatureStream element into java.lang.Class instance
799 static oop get_mirror_from_signature(const methodHandle& method,
800 SignatureStream* ss,
801 TRAPS) {
802
803 BasicType bt = ss->type();
804 if (T_OBJECT == bt || T_ARRAY == bt || T_VALUETYPE == bt) {
805 Symbol* name = ss->as_symbol(CHECK_NULL);
806 oop loader = method->method_holder()->class_loader();
807 oop protection_domain = method->method_holder()->protection_domain();
808 const Klass* k = SystemDictionary::resolve_or_fail(name,
809 Handle(THREAD, loader),
810 Handle(THREAD, protection_domain),
811 true,
812 CHECK_NULL);
813 if (log_is_enabled(Debug, class, resolve)) {
814 trace_class_resolution(k);
815 }
816 return java_mirror((Klass*)k, bt == T_VALUETYPE);
817 }
818
819 assert(bt != T_VOID || ss->at_return_type(),
820 "T_VOID should only appear as return type");
821
822 return java_lang_Class::primitive_mirror(bt);
823 }
824
825 static objArrayHandle get_parameter_types(const methodHandle& method,
826 int parameter_count,
827 oop* return_type,
828 TRAPS) {
829 // Allocate array holding parameter types (java.lang.Class instances)
830 objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle()));
831 objArrayHandle mirrors(THREAD, m);
832 int index = 0;
833 // Collect parameter types
834 ResourceMark rm(THREAD);
835 Symbol* signature = method->signature();
836 SignatureStream ss(signature);
837 while (!ss.at_return_type()) {
838 oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle()));
839 mirrors->obj_at_put(index++, mirror);
840 ss.next();
841 }
842 assert(index == parameter_count, "invalid parameter count");
851 static objArrayHandle get_exception_types(const methodHandle& method, TRAPS) {
852 return method->resolved_checked_exceptions(THREAD);
853 }
854
855 static Handle new_type(Symbol* signature, Klass* k, TRAPS) {
856 // Basic types
857 BasicType type = vmSymbols::signature_type(signature);
858 if (type != T_OBJECT && type != T_VALUETYPE) {
859 return Handle(THREAD, Universe::java_mirror(type));
860 }
861
862 Klass* result =
863 SystemDictionary::resolve_or_fail(signature,
864 Handle(THREAD, k->class_loader()),
865 Handle(THREAD, k->protection_domain()),
866 true, CHECK_(Handle()));
867
868 if (log_is_enabled(Debug, class, resolve)) {
869 trace_class_resolution(result);
870 }
871 oop nt = java_mirror(result, type == T_VALUETYPE);
872 return Handle(THREAD, nt);
873 }
874
875
876 oop Reflection::new_method(const methodHandle& method, bool for_constant_pool_access, TRAPS) {
877 // Allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods.
878 assert(!method()->is_initializer() ||
879 (for_constant_pool_access && method()->is_static()),
880 "should call new_constructor instead");
881 InstanceKlass* holder = method->method_holder();
882 int slot = method->method_idnum();
883
884 Symbol* signature = method->signature();
885 int parameter_count = ArgumentCount(signature).size();
886 oop return_type_oop = NULL;
887 objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL);
888 if (parameter_types.is_null() || return_type_oop == NULL) return NULL;
889
890 Handle return_type(THREAD, return_type_oop);
891
|