< prev index next >

src/hotspot/share/runtime/reflection.cpp

Print this page




  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 


< prev index next >