< prev index next >

src/hotspot/share/prims/jvm.cpp

Print this page
rev 58565 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: duke
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com
rev 58568 : [mq]: hidden-class-4


 972   Handle class_loader (THREAD, JNIHandles::resolve(loader));
 973   if (UsePerfData) {
 974     is_lock_held_by_thread(class_loader,
 975                            ClassLoader::sync_JVMDefineClassLockFreeCounter(),
 976                            THREAD);
 977   }
 978   Handle protection_domain (THREAD, JNIHandles::resolve(pd));
 979   Klass* k = SystemDictionary::resolve_from_stream(class_name,
 980                                                    class_loader,
 981                                                    protection_domain,
 982                                                    &st,
 983                                                    CHECK_NULL);
 984 
 985   if (log_is_enabled(Debug, class, resolve) && k != NULL) {
 986     trace_class_resolution(k);
 987   }
 988 
 989   return (jclass) JNIHandles::make_local(env, k->java_mirror());
 990 }
 991 




















































































































































 992 
 993 JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
 994   JVMWrapper("JVM_DefineClass");
 995 
 996   return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
 997 JVM_END
 998 























 999 
1000 JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))
1001   JVMWrapper("JVM_DefineClassWithSource");
1002 
1003   return jvm_define_class_common(env, name, loader, buf, len, pd, source, THREAD);
1004 JVM_END
1005 
1006 JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name))
1007   JVMWrapper("JVM_FindLoadedClass");
1008   ResourceMark rm(THREAD);
1009 
1010   Handle h_name (THREAD, JNIHandles::resolve_non_null(name));
1011   char* str = java_lang_String::as_utf8_string(h_name());
1012 
1013   // Sanity check, don't expect null
1014   if (str == NULL) return NULL;
1015 
1016   // Internalize the string, converting '.' to '/' in string.
1017   char* p = (char*)str;
1018   while (*p != '\0') {


1141   }
1142   return (jobjectArray) JNIHandles::make_local(env, result());
1143 JVM_END
1144 
1145 
1146 JVM_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls))
1147   JVMWrapper("JVM_IsInterface");
1148   oop mirror = JNIHandles::resolve_non_null(cls);
1149   if (java_lang_Class::is_primitive(mirror)) {
1150     return JNI_FALSE;
1151   }
1152   Klass* k = java_lang_Class::as_Klass(mirror);
1153   jboolean result = k->is_interface();
1154   assert(!result || k->is_instance_klass(),
1155          "all interfaces are instance types");
1156   // The compiler intrinsic for isInterface tests the
1157   // Klass::_access_flags bits in the same way.
1158   return result;
1159 JVM_END
1160 









1161 
1162 JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls))
1163   JVMWrapper("JVM_GetClassSigners");
1164   JvmtiVMObjectAllocEventCollector oam;
1165   if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
1166     // There are no signers for primitive types
1167     return NULL;
1168   }
1169 
1170   objArrayHandle signers(THREAD, java_lang_Class::signers(JNIHandles::resolve_non_null(cls)));
1171 
1172   // If there are no signers set in the class, or if the class
1173   // is an array, return NULL.
1174   if (signers == NULL) return NULL;
1175 
1176   // copy of the signers array
1177   Klass* element = ObjArrayKlass::cast(signers->klass())->element_klass();
1178   objArrayOop signers_copy = oopFactory::new_objArray(element, signers->length(), CHECK_NULL);
1179   for (int index = 0; index < signers->length(); index++) {
1180     signers_copy->obj_at_put(index, signers->obj_at(index));


1408     return (jobjectArray)JNIHandles::make_local(env, res);
1409   }
1410 
1411   return (jobjectArray)JNIHandles::make_local(env, result());
1412 JVM_END
1413 
1414 
1415 JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass))
1416 {
1417   // ofClass is a reference to a java_lang_Class object.
1418   if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
1419       ! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_instance_klass()) {
1420     return NULL;
1421   }
1422 
1423   bool inner_is_member = false;
1424   Klass* outer_klass
1425     = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))
1426                           )->compute_enclosing_class(&inner_is_member, CHECK_NULL);
1427   if (outer_klass == NULL)  return NULL;  // already a top-level class
1428   if (!inner_is_member)  return NULL;     // an anonymous class (inside a method)
1429   return (jclass) JNIHandles::make_local(env, outer_klass->java_mirror());
1430 }
1431 JVM_END
1432 
1433 JVM_ENTRY(jstring, JVM_GetSimpleBinaryName(JNIEnv *env, jclass cls))
1434 {
1435   oop mirror = JNIHandles::resolve_non_null(cls);
1436   if (java_lang_Class::is_primitive(mirror) ||
1437       !java_lang_Class::as_Klass(mirror)->is_instance_klass()) {
1438     return NULL;
1439   }
1440   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
1441   int ooff = 0, noff = 0;
1442   if (k->find_inner_classes_attr(&ooff, &noff, THREAD)) {
1443     if (noff != 0) {
1444       constantPoolHandle i_cp(thread, k->constants());
1445       Symbol* name = i_cp->symbol_at(noff);
1446       Handle str = java_lang_String::create_from_symbol(name, CHECK_NULL);
1447       return (jstring) JNIHandles::make_local(env, str());
1448     }


1858 JVM_ENTRY(jboolean, JVM_AreNestMates(JNIEnv *env, jclass current, jclass member))
1859 {
1860   JVMWrapper("JVM_AreNestMates");
1861   Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
1862   assert(c->is_instance_klass(), "must be");
1863   InstanceKlass* ck = InstanceKlass::cast(c);
1864   Klass* m = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(member));
1865   assert(m->is_instance_klass(), "must be");
1866   InstanceKlass* mk = InstanceKlass::cast(m);
1867   return ck->has_nestmate_access_to(mk, THREAD);
1868 }
1869 JVM_END
1870 
1871 JVM_ENTRY(jclass, JVM_GetNestHost(JNIEnv* env, jclass current))
1872 {
1873   // current is not a primitive or array class
1874   JVMWrapper("JVM_GetNestHost");
1875   Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
1876   assert(c->is_instance_klass(), "must be");
1877   InstanceKlass* ck = InstanceKlass::cast(c);
1878   // Don't post exceptions if validation fails
1879   InstanceKlass* host = ck->nest_host(NULL, THREAD);
1880   return (jclass) (host == NULL ? NULL :
1881                    JNIHandles::make_local(THREAD, host->java_mirror()));
1882 }
1883 JVM_END
1884 
1885 JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current))
1886 {
1887   // current is not a primitive or array class
1888   JVMWrapper("JVM_GetNestMembers");

1889   Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
1890   assert(c->is_instance_klass(), "must be");
1891   InstanceKlass* ck = InstanceKlass::cast(c);
1892   // Get the nest host for this nest - throw ICCE if validation fails
1893   Symbol* icce = vmSymbols::java_lang_IncompatibleClassChangeError();
1894   InstanceKlass* host = ck->nest_host(icce, CHECK_NULL);
1895 


1896   {
1897     JvmtiVMObjectAllocEventCollector oam;
1898     Array<u2>* members = host->nest_members();
1899     int length = members == NULL ? 0 : members->length();



1900     // nest host is first in the array so make it one bigger
1901     objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(),
1902                                              length + 1, CHECK_NULL);
1903     objArrayHandle result (THREAD, r);
1904     result->obj_at_put(0, host->java_mirror());
1905     if (length != 0) {
1906       int i;
1907       for (i = 0; i < length; i++) {
1908          int cp_index = members->at(i);
1909          Klass* k = host->constants()->klass_at(cp_index, CHECK_NULL);














1910          if (k->is_instance_klass()) {
1911            InstanceKlass* nest_host_k =
1912              InstanceKlass::cast(k)->nest_host(icce, CHECK_NULL);
1913            if (nest_host_k == host) {
1914              result->obj_at_put(i+1, k->java_mirror());





1915            }
1916            else {
1917              // k's nest host is legal but it isn't our host so
1918              // throw ICCE
1919              ResourceMark rm(THREAD);
1920              Exceptions::fthrow(THREAD_AND_LOCATION,
1921                                 icce,
1922                                 "Nest member %s in %s declares a different nest host of %s",
1923                                 k->external_name(),
1924                                 host->external_name(),
1925                                 nest_host_k->external_name()
1926                            );
1927              return NULL;
1928            }
1929          }
1930          else {
1931            // we have a bad nest member entry - throw ICCE
1932            ResourceMark rm(THREAD);
1933            Exceptions::fthrow(THREAD_AND_LOCATION,
1934                               icce,
1935                               "Class %s can not be a nest member of %s",
1936                               k->external_name(),
1937                               host->external_name()
1938                               );
1939            return NULL;
1940          }

1941       }
1942     }
1943     else {
1944       assert(host == ck, "must be singleton nest");
1945     }
1946     return (jobjectArray)JNIHandles::make_local(THREAD, result());
1947   }
1948 }
1949 JVM_END
1950 
1951 // Constant pool access //////////////////////////////////////////////////////////
1952 
1953 JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))
1954 {
1955   JVMWrapper("JVM_GetClassConstantPool");
1956   JvmtiVMObjectAllocEventCollector oam;
1957 
1958   // Return null for primitives and arrays
1959   if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
1960     Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
1961     if (k->is_instance_klass()) {
1962       InstanceKlass* k_h = InstanceKlass::cast(k);
1963       Handle jcp = reflect_ConstantPool::create(CHECK_NULL);
1964       reflect_ConstantPool::set_cp(jcp(), k_h->constants());




 972   Handle class_loader (THREAD, JNIHandles::resolve(loader));
 973   if (UsePerfData) {
 974     is_lock_held_by_thread(class_loader,
 975                            ClassLoader::sync_JVMDefineClassLockFreeCounter(),
 976                            THREAD);
 977   }
 978   Handle protection_domain (THREAD, JNIHandles::resolve(pd));
 979   Klass* k = SystemDictionary::resolve_from_stream(class_name,
 980                                                    class_loader,
 981                                                    protection_domain,
 982                                                    &st,
 983                                                    CHECK_NULL);
 984 
 985   if (log_is_enabled(Debug, class, resolve) && k != NULL) {
 986     trace_class_resolution(k);
 987   }
 988 
 989   return (jclass) JNIHandles::make_local(env, k->java_mirror());
 990 }
 991 
 992 enum {
 993   NESTMATE              = java_lang_invoke_MemberName::MN_NESTMATE_CLASS,
 994   HIDDEN_CLASS          = java_lang_invoke_MemberName::MN_HIDDEN_CLASS,
 995   STRONG_LOADER_LINK    = java_lang_invoke_MemberName::MN_STRONG_LOADER_LINK,
 996   ACCESS_VM_ANNOTATIONS = java_lang_invoke_MemberName::MN_ACCESS_VM_ANNOTATIONS
 997 };
 998 
 999 /*
1000  * Define a class with the specified flags that indicates if it's a nestmate,
1001  * hidden, or strongly referenced from class loader.
1002  */
1003 static jclass jvm_lookup_define_class(JNIEnv *env, jclass lookup, const char *name,
1004                                       const jbyte *buf, jsize len, jobject pd,
1005                                       jboolean init, int flags, jobject classData, TRAPS) {
1006   assert(THREAD->is_Java_thread(), "must be a JavaThread");
1007   JavaThread* jt = (JavaThread*) THREAD;
1008   ResourceMark rm(THREAD);
1009 
1010   Klass* lookup_k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(lookup));
1011   // Lookup class must be a non-null instance
1012   if (lookup_k == NULL) {
1013     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null");
1014   }
1015   assert(lookup_k->is_instance_klass(), "Lookup class must be an instance klass");
1016 
1017   Handle class_loader (THREAD, lookup_k->class_loader());
1018 
1019   bool is_nestmate = (flags & NESTMATE) == NESTMATE;
1020   bool is_hidden = (flags & HIDDEN_CLASS) == HIDDEN_CLASS;
1021   bool is_strong = (flags & STRONG_LOADER_LINK) == STRONG_LOADER_LINK;
1022   bool vm_annotations = (flags & ACCESS_VM_ANNOTATIONS) == ACCESS_VM_ANNOTATIONS;
1023 
1024   InstanceKlass* host_class = NULL;
1025   if (is_nestmate) {
1026     host_class = InstanceKlass::cast(lookup_k)->nest_host(CHECK_NULL);
1027   }
1028 
1029   log_info(class, nestmates)("LookupDefineClass: %s - %s%s, %s, %s, %s",
1030                              name,
1031                              is_nestmate ? "with dynamic nest-host " : "non-nestmate",
1032                              is_nestmate ? host_class->external_name() : "",
1033                              is_hidden ? "hidden" : "not hidden",
1034                              is_strong ? "strong" : "weak",
1035                              vm_annotations ? "with vm annotations" : "without vm annotation");
1036 
1037   if (!is_hidden) {
1038     // classData is only applicable for hidden classes
1039     if (classData != NULL) {
1040       THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "classData is only applicable for hidden classes");
1041     }
1042     if (is_nestmate) {
1043       THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "dynamic nestmate is only applicable for hidden classes");
1044     }
1045     if (!is_strong) {
1046       THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "an ordinary class must be strongly referenced by its defining loader");
1047     }
1048     if (vm_annotations) {
1049       THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "vm annotations only allowed for hidden classes");
1050     }
1051     if (flags != STRONG_LOADER_LINK) {
1052       THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1053                   err_msg("invalid flag 0x%x", flags));
1054     }
1055   }
1056 
1057 
1058   // Since exceptions can be thrown, class initialization can take place
1059   // if name is NULL no check for class name in .class stream has to be made.
1060   TempNewSymbol class_name = NULL;
1061   if (name != NULL) {
1062     const int str_len = (int)strlen(name);
1063     if (str_len > Symbol::max_length()) {
1064       // It's impossible to create this class;  the name cannot fit
1065       // into the constant pool.
1066       Exceptions::fthrow(THREAD_AND_LOCATION,
1067                          vmSymbols::java_lang_NoClassDefFoundError(),
1068                          "Class name exceeds maximum length of %d: %s",
1069                          Symbol::max_length(),
1070                          name);
1071       return 0;
1072     }
1073     class_name = SymbolTable::new_symbol(name, str_len);
1074   }
1075 
1076   Handle protection_domain (THREAD, JNIHandles::resolve(pd));
1077   const char* source = is_nestmate ? host_class->external_name() : "__JVM_LookupDefineClass__";
1078   ClassFileStream st((u1*)buf, len, source, ClassFileStream::verify);
1079 
1080   Klass* defined_k;
1081   InstanceKlass* ik = NULL;
1082   if (!is_hidden) {
1083     defined_k = SystemDictionary::resolve_from_stream(class_name,
1084                                                       class_loader,
1085                                                       protection_domain,
1086                                                       &st,
1087                                                       CHECK_NULL);
1088 
1089     if (log_is_enabled(Debug, class, resolve) && defined_k != NULL) {
1090       trace_class_resolution(defined_k);
1091     }
1092     ik = InstanceKlass::cast(defined_k);
1093   } else { // hidden
1094     Handle classData_h(THREAD, JNIHandles::resolve(classData));
1095     ClassLoadInfo cl_info(protection_domain,
1096                           NULL, // unsafe_anonymous_host
1097                           NULL, // cp_patches
1098                           host_class,
1099                           classData_h,
1100                           is_hidden,
1101                           is_strong,
1102                           vm_annotations);
1103     defined_k = SystemDictionary::parse_stream(class_name,
1104                                                class_loader,
1105                                                &st,
1106                                                cl_info,
1107                                                CHECK_NULL);
1108     if (defined_k == NULL) {
1109       THROW_MSG_0(vmSymbols::java_lang_Error(), "Failure to define a hidden class");
1110     }
1111 
1112     ik = InstanceKlass::cast(defined_k);
1113 
1114     // The hidden class loader data has been artificially been kept alive to
1115     // this point. The mirror and any instances of this class have to keep
1116     // it alive afterwards.
1117     ik->class_loader_data()->dec_keep_alive();
1118 
1119     if (is_nestmate && log_is_enabled(Debug, class, nestmates)) {
1120       ModuleEntry* module = ik->module();
1121       const char * module_name = module->is_named() ? module->name()->as_C_string() : UNNAMED_MODULE;
1122       log_debug(class, nestmates)("Dynamic nestmate: %s/%s, nest_host %s, %s",
1123                                   module_name,
1124                                   ik->external_name(),
1125                                   host_class->external_name(),
1126                                   ik->is_hidden() ? "is hidden" : "is not hidden");
1127     }
1128   }
1129   assert(Reflection::is_same_class_package(lookup_k, defined_k),
1130          "lookup class and defined class are in different packages");
1131 
1132   if (init) {
1133     ik->initialize(CHECK_NULL);
1134   } else {
1135     ik->link_class(CHECK_NULL);
1136   }
1137 
1138   return (jclass) JNIHandles::make_local(env, defined_k->java_mirror());
1139 }
1140 
1141 JVM_ENTRY(jclass, JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd))
1142   JVMWrapper("JVM_DefineClass");
1143 
1144   return jvm_define_class_common(env, name, loader, buf, len, pd, NULL, THREAD);
1145 JVM_END
1146 
1147 /*
1148  * Define a class with the specified lookup class.
1149  *  lookup:  Lookup class
1150  *  name:    the name of the class
1151  *  buf:     class bytes
1152  *  len:     length of class bytes
1153  *  pd:      protection domain
1154  *  init:    initialize the class
1155  *  flags:   properties of the class
1156  *  classData: private static pre-initialized field
1157  */
1158 JVM_ENTRY(jclass, JVM_LookupDefineClass(JNIEnv *env, jclass lookup, const char *name, const jbyte *buf,
1159           jsize len, jobject pd, jboolean initialize, int flags, jobject classData))
1160   JVMWrapper("JVM_LookupDefineClass");
1161 
1162   if (lookup == NULL) {
1163     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Lookup class is null");
1164   }
1165 
1166   assert(buf != NULL, "buf must not be NULL");
1167 
1168   return jvm_lookup_define_class(env, lookup, name, buf, len, pd, initialize, flags, classData, THREAD);
1169 JVM_END
1170 
1171 JVM_ENTRY(jclass, JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source))
1172   JVMWrapper("JVM_DefineClassWithSource");
1173 
1174   return jvm_define_class_common(env, name, loader, buf, len, pd, source, THREAD);
1175 JVM_END
1176 
1177 JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name))
1178   JVMWrapper("JVM_FindLoadedClass");
1179   ResourceMark rm(THREAD);
1180 
1181   Handle h_name (THREAD, JNIHandles::resolve_non_null(name));
1182   char* str = java_lang_String::as_utf8_string(h_name());
1183 
1184   // Sanity check, don't expect null
1185   if (str == NULL) return NULL;
1186 
1187   // Internalize the string, converting '.' to '/' in string.
1188   char* p = (char*)str;
1189   while (*p != '\0') {


1312   }
1313   return (jobjectArray) JNIHandles::make_local(env, result());
1314 JVM_END
1315 
1316 
1317 JVM_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls))
1318   JVMWrapper("JVM_IsInterface");
1319   oop mirror = JNIHandles::resolve_non_null(cls);
1320   if (java_lang_Class::is_primitive(mirror)) {
1321     return JNI_FALSE;
1322   }
1323   Klass* k = java_lang_Class::as_Klass(mirror);
1324   jboolean result = k->is_interface();
1325   assert(!result || k->is_instance_klass(),
1326          "all interfaces are instance types");
1327   // The compiler intrinsic for isInterface tests the
1328   // Klass::_access_flags bits in the same way.
1329   return result;
1330 JVM_END
1331 
1332 JVM_ENTRY(jboolean, JVM_IsHiddenClass(JNIEnv *env, jclass cls))
1333   JVMWrapper("JVM_IsHiddenClass");
1334   oop mirror = JNIHandles::resolve_non_null(cls);
1335   if (java_lang_Class::is_primitive(mirror)) {
1336     return JNI_FALSE;
1337   }
1338   Klass* k = java_lang_Class::as_Klass(mirror);
1339   return k->is_hidden();
1340 JVM_END
1341 
1342 JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls))
1343   JVMWrapper("JVM_GetClassSigners");
1344   JvmtiVMObjectAllocEventCollector oam;
1345   if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
1346     // There are no signers for primitive types
1347     return NULL;
1348   }
1349 
1350   objArrayHandle signers(THREAD, java_lang_Class::signers(JNIHandles::resolve_non_null(cls)));
1351 
1352   // If there are no signers set in the class, or if the class
1353   // is an array, return NULL.
1354   if (signers == NULL) return NULL;
1355 
1356   // copy of the signers array
1357   Klass* element = ObjArrayKlass::cast(signers->klass())->element_klass();
1358   objArrayOop signers_copy = oopFactory::new_objArray(element, signers->length(), CHECK_NULL);
1359   for (int index = 0; index < signers->length(); index++) {
1360     signers_copy->obj_at_put(index, signers->obj_at(index));


1588     return (jobjectArray)JNIHandles::make_local(env, res);
1589   }
1590 
1591   return (jobjectArray)JNIHandles::make_local(env, result());
1592 JVM_END
1593 
1594 
1595 JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass))
1596 {
1597   // ofClass is a reference to a java_lang_Class object.
1598   if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) ||
1599       ! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_instance_klass()) {
1600     return NULL;
1601   }
1602 
1603   bool inner_is_member = false;
1604   Klass* outer_klass
1605     = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))
1606                           )->compute_enclosing_class(&inner_is_member, CHECK_NULL);
1607   if (outer_klass == NULL)  return NULL;  // already a top-level class
1608   if (!inner_is_member)  return NULL;     // a hidden or unsafe anonymous class (inside a method)
1609   return (jclass) JNIHandles::make_local(env, outer_klass->java_mirror());
1610 }
1611 JVM_END
1612 
1613 JVM_ENTRY(jstring, JVM_GetSimpleBinaryName(JNIEnv *env, jclass cls))
1614 {
1615   oop mirror = JNIHandles::resolve_non_null(cls);
1616   if (java_lang_Class::is_primitive(mirror) ||
1617       !java_lang_Class::as_Klass(mirror)->is_instance_klass()) {
1618     return NULL;
1619   }
1620   InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(mirror));
1621   int ooff = 0, noff = 0;
1622   if (k->find_inner_classes_attr(&ooff, &noff, THREAD)) {
1623     if (noff != 0) {
1624       constantPoolHandle i_cp(thread, k->constants());
1625       Symbol* name = i_cp->symbol_at(noff);
1626       Handle str = java_lang_String::create_from_symbol(name, CHECK_NULL);
1627       return (jstring) JNIHandles::make_local(env, str());
1628     }


2038 JVM_ENTRY(jboolean, JVM_AreNestMates(JNIEnv *env, jclass current, jclass member))
2039 {
2040   JVMWrapper("JVM_AreNestMates");
2041   Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
2042   assert(c->is_instance_klass(), "must be");
2043   InstanceKlass* ck = InstanceKlass::cast(c);
2044   Klass* m = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(member));
2045   assert(m->is_instance_klass(), "must be");
2046   InstanceKlass* mk = InstanceKlass::cast(m);
2047   return ck->has_nestmate_access_to(mk, THREAD);
2048 }
2049 JVM_END
2050 
2051 JVM_ENTRY(jclass, JVM_GetNestHost(JNIEnv* env, jclass current))
2052 {
2053   // current is not a primitive or array class
2054   JVMWrapper("JVM_GetNestHost");
2055   Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
2056   assert(c->is_instance_klass(), "must be");
2057   InstanceKlass* ck = InstanceKlass::cast(c);
2058   InstanceKlass* host = ck->nest_host(THREAD);

2059   return (jclass) (host == NULL ? NULL :
2060                    JNIHandles::make_local(THREAD, host->java_mirror()));
2061 }
2062 JVM_END
2063 
2064 JVM_ENTRY(jobjectArray, JVM_GetNestMembers(JNIEnv* env, jclass current))
2065 {
2066   // current is not a primitive or array class
2067   JVMWrapper("JVM_GetNestMembers");
2068   ResourceMark rm(THREAD);
2069   Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current));
2070   assert(c->is_instance_klass(), "must be");
2071   InstanceKlass* ck = InstanceKlass::cast(c);
2072   InstanceKlass* host = ck->nest_host(THREAD);


2073 
2074   log_trace(class, nestmates)("Calling GetNestMembers for type %s with nest-host %s",
2075                               ck->external_name(), host->external_name());
2076   {
2077     JvmtiVMObjectAllocEventCollector oam;
2078     Array<u2>* members = host->nest_members();
2079     int length = members == NULL ? 0 : members->length();
2080 
2081     log_trace(class, nestmates)(" - host has %d listed nest members", length);
2082 
2083     // nest host is first in the array so make it one bigger
2084     objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(),
2085                                              length + 1, CHECK_NULL);
2086     objArrayHandle result(THREAD, r);
2087     result->obj_at_put(0, host->java_mirror());
2088     if (length != 0) {
2089       int count = 0;
2090       for (int i = 0; i < length; i++) {
2091         int cp_index = members->at(i);
2092         Klass* k = host->constants()->klass_at(cp_index, THREAD);
2093         if (HAS_PENDING_EXCEPTION) {
2094           if (PENDING_EXCEPTION->is_a(SystemDictionary::VirtualMachineError_klass())) {
2095             return NULL; // propagate VMEs
2096           }
2097           if (log_is_enabled(Trace, class, nestmates)) {
2098             stringStream ss;
2099             char* target_member_class = host->constants()->klass_name_at(cp_index)->as_C_string();
2100             ss.print(" - resolution of nest member %s failed: ", target_member_class);
2101             java_lang_Throwable::print(PENDING_EXCEPTION, &ss);
2102             log_trace(class, nestmates)("%s", ss.as_string());
2103           }
2104           CLEAR_PENDING_EXCEPTION;
2105           continue;
2106         }
2107         if (k->is_instance_klass()) {
2108           InstanceKlass* ik = InstanceKlass::cast(k);
2109           InstanceKlass* nest_host_k = ik->nest_host(CHECK_NULL);
2110           if (nest_host_k == host) {
2111             result->obj_at_put(count+1, k->java_mirror());
2112             count++;
2113             log_trace(class, nestmates)(" - [%d] = %s", count, ik->external_name());
2114           } else {
2115             log_trace(class, nestmates)(" - skipping member %s with different host %s",
2116                                         ik->external_name(), nest_host_k->external_name());
2117           }
2118         } else {
2119           log_trace(class, nestmates)(" - skipping member %s that is not an instance class",
2120                                       k->external_name());









2121         }
2122       }
2123       if (count < length) {
2124         // we had invalid entries so we need to compact the array
2125         log_trace(class, nestmates)(" - compacting array from length %d to %d",
2126                                     length + 1, count + 1);
2127 
2128         objArrayOop r2 = oopFactory::new_objArray(SystemDictionary::Class_klass(),
2129                                                   count + 1, CHECK_NULL);
2130         objArrayHandle result2(THREAD, r2);
2131         for (int i = 0; i < count + 1; i++) {
2132           result2->obj_at_put(i, result->obj_at(i));
2133         }
2134         return (jobjectArray)JNIHandles::make_local(THREAD, result2());
2135       }
2136     }
2137     else {
2138       assert(host == ck || ck->is_hidden(), "must be singleton nest or dynamic nestmate");
2139     }
2140     return (jobjectArray)JNIHandles::make_local(THREAD, result());
2141   }
2142 }
2143 JVM_END
2144 
2145 // Constant pool access //////////////////////////////////////////////////////////
2146 
2147 JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))
2148 {
2149   JVMWrapper("JVM_GetClassConstantPool");
2150   JvmtiVMObjectAllocEventCollector oam;
2151 
2152   // Return null for primitives and arrays
2153   if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) {
2154     Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
2155     if (k->is_instance_klass()) {
2156       InstanceKlass* k_h = InstanceKlass::cast(k);
2157       Handle jcp = reflect_ConstantPool::create(CHECK_NULL);
2158       reflect_ConstantPool::set_cp(jcp(), k_h->constants());


< prev index next >