< prev index next >

src/hotspot/share/oops/instanceKlass.cpp

Print this page

        

@@ -326,10 +326,56 @@
     }
   }
   return nest_host_k;
 }
 
+
+// Dynamic nest member support: set this class's nest host to the given class.
+// This occurs as part of the class definition, as soon as the instanceKlass
+// has been created and doesn't require further resolution. The code:
+//    lookup().defineClass(bytes_for_X, NESTMATE);
+// results in:
+//    class_of_X.set_nest_host(lookup().lookupClass().getNestHost())
+// So we know that current class is "pristine" and its _nest_host must be NULL.
+// We also know the "host" is a valid nest-host in the same package so we can
+// assert some of those facts.
+void InstanceKlass::set_nest_host(InstanceKlass* host, TRAPS) {
+  assert(host != NULL, "NULL nest host specified");
+  assert(_nest_host == NULL, "current class has resolved nest-host");
+  assert((host->_nest_host == NULL && host->_nest_host_index == 0) ||
+         (host->_nest_host == host), "proposed host is not a valid nest-host");
+  // Can't assert this as package is not set yet:
+  // assert(is_same_class_package(host), "proposed host is in wrong package");
+
+  const char * error_msg = NULL;
+  // There are two validity checks that have to be made:
+  // 1. The current class must not expect a statically defined nest-host
+  if (_nest_host_index == 0) {
+    // 2. The current class can't itself be a nest-host
+    if (_nest_members == NULL ||
+        _nest_members == Universe::the_empty_short_array()) {
+      _nest_host = host;
+      return;
+    }
+    else {
+      error_msg = "the current class is already a nest-host";
+    }
+  }
+  else {
+    error_msg = "the current class is already a member of a nest";
+  }
+
+  ResourceMark rm(THREAD);
+  Exceptions::fthrow(THREAD_AND_LOCATION,
+                     vmSymbols::java_lang_ClassFormatError(),
+                     "Type %s can not be a dynamic nest member of %s: %s",
+                     this->external_name(),
+                     host->external_name(),
+                     error_msg
+                     );
+}
+
 // check if 'this' and k are nestmates (same nest_host), or k is our nest_host,
 // or we are k's nest_host - all of which is covered by comparing the two
 // resolved_nest_hosts
 bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) {
 

@@ -367,11 +413,11 @@
 InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) {
   const int size = InstanceKlass::size(parser.vtable_size(),
                                        parser.itable_size(),
                                        nonstatic_oop_map_size(parser.total_oop_map_count()),
                                        parser.is_interface(),
-                                       parser.is_unsafe_anonymous(),
+                                       (parser.is_nonfindable() || parser.is_unsafe_anonymous()),
                                        should_store_fingerprint(parser.is_unsafe_anonymous()));
 
   const Symbol* const class_name = parser.class_name();
   assert(class_name != NULL, "invariant");
   ClassLoaderData* loader_data = parser.loader_data();

@@ -439,10 +485,11 @@
   _reference_type(parser.reference_type())
 {
   set_vtable_length(parser.vtable_size());
   set_kind(kind);
   set_access_flags(parser.access_flags());
+  set_is_nonfindable(parser.is_nonfindable());
   set_is_unsafe_anonymous(parser.is_unsafe_anonymous());
   set_layout_helper(Klass::instance_layout_helper(parser.layout_size(),
                                                     false));
 
   assert(NULL == _methods, "underlying memory not zeroed?");

@@ -2214,23 +2261,23 @@
   }
 
   return true;
 }
 
-bool InstanceKlass::should_store_fingerprint(bool is_unsafe_anonymous) {
+bool InstanceKlass::should_store_fingerprint(bool is_nonfindable) {
 #if INCLUDE_AOT
   // We store the fingerprint into the InstanceKlass only in the following 2 cases:
   if (CalculateClassFingerprint) {
     // (1) We are running AOT to generate a shared library.
     return true;
   }
   if (DumpSharedSpaces) {
     // (2) We are running -Xshare:dump to create a shared archive
     return true;
   }
-  if (UseAOT && is_unsafe_anonymous) {
-    // (3) We are using AOT code from a shared library and see an unsafe anonymous class
+  if (UseAOT && is_nonfindable) {
+    // (3) We are using AOT code from a shared library and see a nonfindable or unsafe anonymous class
     return true;
   }
 #endif
 
   // In all other cases we might set the _misc_has_passed_fingerprint_check bit,

@@ -2533,10 +2580,11 @@
   }
 #endif
 
   // Decrement symbol reference counts associated with the unloaded class.
   if (_name != NULL) _name->decrement_refcount();
+
   // unreference array name derived from this class name (arrays of an unloaded
   // class can't be referenced anymore).
   if (_array_name != NULL)  _array_name->decrement_refcount();
   if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension);
 }

@@ -2619,10 +2667,29 @@
   if (is_unsafe_anonymous()) {
     assert(unsafe_anonymous_host() != NULL, "unsafe anonymous class must have a host class");
     return unsafe_anonymous_host()->module();
   }
 
+  if (is_nonfindable() &&
+      in_unnamed_package() &&
+      class_loader_data()->is_shortlived()) {
+    // For a weak nonfindable class defined to an unnamed package,
+    // the short-lived CLD will not have an unnamed module created for it.
+    // Two choices to find the correct ModuleEntry:
+    // 1. If nonfindable class is within a nest, use nest host's module
+    // 2. Find the unnamed module off from the class loader
+    // For now option #2 is used since a nest host is not set until
+    // after the instance class is created in jvm_lookup_define_class().
+    if (class_loader_data()->is_boot_class_loader_data()) {
+      return ClassLoaderData::the_null_class_loader_data()->unnamed_module();
+    } else {
+      oop module = java_lang_ClassLoader::unnamedModule(class_loader_data()->class_loader());
+      assert(java_lang_Module::is_instance(module), "Not an instance of java.lang.Module");
+      return java_lang_Module::module_entry(module);
+    }
+  }
+
   // Class is in a named package
   if (!in_unnamed_package()) {
     return _package_entry->module();
   }
 
< prev index next >