src/hotspot/share/memory/metaspaceShared.cpp
changeset 52514 f4e3900c8d08
parent 52503 7d3b82b338f7
child 52562 3a9384c12260
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Tue Nov 13 21:43:10 2018 -0500
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Wed Nov 07 19:40:27 2018 -0800
@@ -64,7 +64,6 @@
 #include "utilities/align.hpp"
 #include "utilities/bitMap.hpp"
 #include "utilities/defaultStream.hpp"
-#include "utilities/hashtable.inline.hpp"
 #if INCLUDE_G1GC
 #include "gc/g1/g1CollectedHeap.hpp"
 #endif
@@ -124,6 +123,15 @@
       MetaspaceShared::report_out_of_space(_name, newtop - _top);
       ShouldNotReachHere();
     }
+    uintx delta = MetaspaceShared::object_delta_uintx(newtop);
+    if (delta > MAX_SHARED_DELTA) {
+      // This is just a sanity check and should not appear in any real world usage. This
+      // happens only if you allocate more than 2GB of shared objects and would require
+      // millions of shared classes.
+      vm_exit_during_initialization("Out of memory in the CDS archive",
+                                    "Please reduce the number of shared classes.");
+    }
+
     MetaspaceShared::commit_shared_space_to(newtop);
     _top = newtop;
     return _top;
@@ -323,6 +331,7 @@
   }
 
   _mc_region.init(&_shared_rs);
+  SharedBaseAddress = (size_t)_shared_rs.base();
   tty->print_cr("Allocated shared space: " SIZE_FORMAT " bytes at " PTR_FORMAT,
                 _shared_rs.size(), p2i(_shared_rs.base()));
 }
@@ -416,6 +425,7 @@
   SymbolTable::serialize_shared_table_header(soc);
   StringTable::serialize_shared_table_header(soc);
   HeapShared::serialize_subgraph_info_table_header(soc);
+  SystemDictionaryShared::serialize_dictionary_headers(soc);
 
   JavaClasses::serialize_offsets(soc);
   InstanceMirrorKlass::serialize_offsets(soc);
@@ -464,13 +474,11 @@
 
 class CollectClassesClosure : public KlassClosure {
   void do_klass(Klass* k) {
-    if (!(k->is_instance_klass() && InstanceKlass::cast(k)->is_in_error_state())) {
-      if (k->is_instance_klass() && InstanceKlass::cast(k)->signers() != NULL) {
-        // Mark any class with signers and don't add to the _global_klass_objects
-        k->set_has_signer_and_not_archived();
-      } else {
-        _global_klass_objects->append_if_missing(k);
-      }
+    if (k->is_instance_klass() &&
+        SystemDictionaryShared::is_excluded_class(InstanceKlass::cast(k))) {
+      // Don't add to the _global_klass_objects
+    } else {
+      _global_klass_objects->append_if_missing(k);
     }
     if (k->is_array_klass()) {
       // Add in the array classes too
@@ -577,16 +585,6 @@
   }
 }
 
-NOT_PRODUCT(
-static void assert_not_unsafe_anonymous_class(InstanceKlass* k) {
-  assert(!(k->is_unsafe_anonymous()), "cannot archive unsafe anonymous classes");
-}
-
-// Unsafe anonymous classes are not stored inside any dictionaries.
-static void assert_no_unsafe_anonymous_classes_in_dictionaries() {
-  ClassLoaderDataGraph::dictionary_classes_do(assert_not_unsafe_anonymous_class);
-})
-
 // Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables.
 // (In GCC this is the field <Type>::_vptr, i.e., first word in the object.)
 //
@@ -1123,6 +1121,17 @@
       newtop = _ro_region.top();
     } else {
       oldtop = _rw_region.top();
+      if (ref->msotype() == MetaspaceObj::ClassType) {
+        // Save a pointer immediate in front of an InstanceKlass, so
+        // we can do a quick lookup from InstanceKlass* -> RunTimeSharedClassInfo*
+        // without building another hashtable. See RunTimeSharedClassInfo::get_for()
+        // in systemDictionaryShared.cpp.
+        Klass* klass = (Klass*)obj;
+        if (klass->is_instance_klass()) {
+          SystemDictionaryShared::validate_before_archiving(InstanceKlass::cast(klass));
+          _rw_region.allocate(sizeof(address), BytesPerWord);
+        }
+      }
       p = _rw_region.allocate(bytes, alignment);
       newtop = _rw_region.top();
     }
@@ -1132,16 +1141,6 @@
     assert(isnew, "must be");
 
     _alloc_stats->record(ref->msotype(), int(newtop - oldtop), read_only);
-    if (ref->msotype() == MetaspaceObj::SymbolType) {
-      uintx delta = MetaspaceShared::object_delta(p);
-      if (delta > MAX_SHARED_DELTA) {
-        // This is just a sanity check and should not appear in any real world usage. This
-        // happens only if you allocate more than 2GB of Symbols and would require
-        // millions of shared classes.
-        vm_exit_during_initialization("Too many Symbols in the CDS archive",
-                                      "Please reduce the number of shared classes.");
-      }
-    }
   }
 
   static address get_new_loc(MetaspaceClosure::Ref* ref) {
@@ -1281,7 +1280,7 @@
       }
     }
     FileMapInfo::metaspace_pointers_do(it);
-    SystemDictionary::classes_do(it);
+    SystemDictionaryShared::dumptime_classes_do(it);
     Universe::metaspace_pointers_do(it);
     SymbolTable::metaspace_pointers_do(it);
     vmSymbols::metaspace_pointers_do(it);
@@ -1315,9 +1314,6 @@
 
 char* VM_PopulateDumpSharedSpace::dump_read_only_tables() {
   ArchiveCompactor::OtherROAllocMark mark;
-  // Reorder the system dictionary. Moving the symbols affects
-  // how the hash table indices are calculated.
-  SystemDictionary::reorder_dictionary_for_sharing();
 
   tty->print("Removing java_mirror ... ");
   if (!HeapShared::is_heap_object_archiving_allowed()) {
@@ -1325,15 +1321,10 @@
   }
   remove_java_mirror_in_classes();
   tty->print_cr("done. ");
-  NOT_PRODUCT(SystemDictionary::verify();)
 
-  size_t buckets_bytes = SystemDictionary::count_bytes_for_buckets();
-  char* buckets_top = _ro_region.allocate(buckets_bytes, sizeof(intptr_t));
-  SystemDictionary::copy_buckets(buckets_top, _ro_region.top());
+  SystemDictionaryShared::write_to_archive();
 
-  size_t table_bytes = SystemDictionary::count_bytes_for_table();
-  char* table_top = _ro_region.allocate(table_bytes, sizeof(intptr_t));
-  SystemDictionary::copy_table(table_top, _ro_region.top());
+  char* start = _ro_region.top();
 
   // Write the other data to the output array.
   WriteClosure wc(&_ro_region);
@@ -1342,7 +1333,7 @@
   // Write the bitmaps for patching the archive heap regions
   dump_archive_heap_oopmaps();
 
-  return buckets_top;
+  return start;
 }
 
 void VM_PopulateDumpSharedSpace::doit() {
@@ -1367,14 +1358,11 @@
             "loader constraints are not saved");
   guarantee(SystemDictionary::placeholders()->number_of_entries() == 0,
           "placeholders are not saved");
-  // Revisit and implement this if we prelink method handle call sites:
-  guarantee(SystemDictionary::invoke_method_table() == NULL ||
-            SystemDictionary::invoke_method_table()->number_of_entries() == 0,
-            "invoke method table is not saved");
 
   // At this point, many classes have been loaded.
   // Gather systemDictionary classes in a global array and do everything to
   // that so we don't have to walk the SystemDictionary again.
+  SystemDictionaryShared::check_excluded_classes();
   _global_klass_objects = new GrowableArray<Klass*>(1000);
   CollectClassesClosure collect_classes;
   ClassLoaderDataGraph::loaded_classes_do(&collect_classes);
@@ -1403,21 +1391,11 @@
   rewrite_nofast_bytecodes_and_calculate_fingerprints();
   tty->print_cr("done. ");
 
-  // Move classes from platform/system dictionaries into the boot dictionary
-  SystemDictionary::combine_shared_dictionaries();
-
-  // Make sure all classes have a correct loader type.
-  ClassLoaderData::the_null_class_loader_data()->dictionary()->classes_do(MetaspaceShared::check_shared_class_loader_type);
-
   // Remove all references outside the metadata
   tty->print("Removing unshareable information ... ");
   remove_unshareable_in_classes();
   tty->print_cr("done. ");
 
-  // We don't support archiving unsafe anonymous classes. Verify that they are not stored in
-  // any dictionaries.
-  NOT_PRODUCT(assert_no_unsafe_anonymous_classes_in_dictionaries());
-
   ArchiveCompactor::initialize();
   ArchiveCompactor::copy_and_compact();
 
@@ -1466,6 +1444,7 @@
   mapinfo->set_core_spaces_size(core_spaces_size);
 
   for (int pass=1; pass<=2; pass++) {
+    bool print_archive_log = (pass==1);
     if (pass == 1) {
       // The first pass doesn't actually write the data to disk. All it
       // does is to update the fields in the mapinfo->_header.
@@ -1490,12 +1469,14 @@
                                         _closed_archive_heap_regions,
                                         _closed_archive_heap_oopmaps,
                                         MetaspaceShared::first_closed_archive_heap_region,
-                                        MetaspaceShared::max_closed_archive_heap_region);
+                                        MetaspaceShared::max_closed_archive_heap_region,
+                                        print_archive_log);
     _total_open_archive_region_size = mapinfo->write_archive_heap_regions(
                                         _open_archive_heap_regions,
                                         _open_archive_heap_oopmaps,
                                         MetaspaceShared::first_open_archive_heap_region,
-                                        MetaspaceShared::max_open_archive_heap_region);
+                                        MetaspaceShared::max_open_archive_heap_region,
+                                        print_archive_log);
   }
 
   mapinfo->close();
@@ -1608,17 +1589,6 @@
   }
 };
 
-void MetaspaceShared::check_shared_class_loader_type(InstanceKlass* ik) {
-  ResourceMark rm;
-  if (ik->shared_classpath_index() == UNREGISTERED_INDEX) {
-    guarantee(ik->loader_type() == 0,
-            "Class loader type must not be set for this class %s", ik->name()->as_C_string());
-  } else {
-    guarantee(ik->loader_type() != 0,
-            "Class loader type must be set for this class %s", ik->name()->as_C_string());
-  }
-}
-
 void MetaspaceShared::link_and_cleanup_shared_classes(TRAPS) {
   // We need to iterate because verification may cause additional classes
   // to be loaded.
@@ -1639,9 +1609,6 @@
       check_closure.reset();
       ClassLoaderDataGraph::unlocked_loaded_classes_do(&check_closure);
     } while (check_closure.made_progress());
-
-    // Unverifiable classes will not be included in the CDS archive.
-    SystemDictionary::remove_classes_in_error_state();
   }
 }
 
@@ -1717,10 +1684,6 @@
     link_and_cleanup_shared_classes(CATCH);
     tty->print_cr("Rewriting and linking classes: done");
 
-    SystemDictionary::clear_invoke_method_table();
-
-    SystemDictionaryShared::finalize_verification_constraints();
-
     VM_PopulateDumpSharedSpace op;
     VMThread::execute(&op);
   }
@@ -1731,36 +1694,36 @@
   ClassListParser parser(class_list_path);
   int class_count = 0;
 
-    while (parser.parse_one_line()) {
-      Klass* klass = ClassLoaderExt::load_one_class(&parser, THREAD);
-      if (HAS_PENDING_EXCEPTION) {
-        if (klass == NULL &&
-             (PENDING_EXCEPTION->klass()->name() == vmSymbols::java_lang_ClassNotFoundException())) {
-          // print a warning only when the pending exception is class not found
-          tty->print_cr("Preload Warning: Cannot find %s", parser.current_class_name());
-        }
-        CLEAR_PENDING_EXCEPTION;
+  while (parser.parse_one_line()) {
+    Klass* klass = parser.load_current_class(THREAD);
+    if (HAS_PENDING_EXCEPTION) {
+      if (klass == NULL &&
+          (PENDING_EXCEPTION->klass()->name() == vmSymbols::java_lang_ClassNotFoundException())) {
+        // print a warning only when the pending exception is class not found
+        tty->print_cr("Preload Warning: Cannot find %s", parser.current_class_name());
+      }
+      CLEAR_PENDING_EXCEPTION;
+    }
+    if (klass != NULL) {
+      if (log_is_enabled(Trace, cds)) {
+        ResourceMark rm;
+        log_trace(cds)("Shared spaces preloaded: %s", klass->external_name());
       }
-      if (klass != NULL) {
-        if (log_is_enabled(Trace, cds)) {
-          ResourceMark rm;
-          log_trace(cds)("Shared spaces preloaded: %s", klass->external_name());
-        }
 
-        if (klass->is_instance_klass()) {
-          InstanceKlass* ik = InstanceKlass::cast(klass);
+      if (klass->is_instance_klass()) {
+        InstanceKlass* ik = InstanceKlass::cast(klass);
 
-          // Link the class to cause the bytecodes to be rewritten and the
-          // cpcache to be created. The linking is done as soon as classes
-          // are loaded in order that the related data structures (klass and
-          // cpCache) are located together.
-          try_link_class(ik, THREAD);
-          guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
-        }
+        // Link the class to cause the bytecodes to be rewritten and the
+        // cpcache to be created. The linking is done as soon as classes
+        // are loaded in order that the related data structures (klass and
+        // cpCache) are located together.
+        try_link_class(ik, THREAD);
+        guarantee(!HAS_PENDING_EXCEPTION, "exception in link_class");
+      }
 
-        class_count++;
-      }
+      class_count++;
     }
+  }
 
   return class_count;
 }
@@ -1994,21 +1957,6 @@
 
   // The rest of the data is now stored in the RW region
   buffer = mapinfo->read_only_tables_start();
-  int sharedDictionaryLen = *(intptr_t*)buffer;
-  buffer += sizeof(intptr_t);
-  int number_of_entries = *(intptr_t*)buffer;
-  buffer += sizeof(intptr_t);
-  SystemDictionary::set_shared_dictionary((HashtableBucket<mtClass>*)buffer,
-                                          sharedDictionaryLen,
-                                          number_of_entries);
-  buffer += sharedDictionaryLen;
-
-  // The following data are the linked list elements
-  // (HashtableEntry objects) for the shared dictionary table.
-
-  int len = *(intptr_t*)buffer;     // skip over shared dictionary entries
-  buffer += sizeof(intptr_t);
-  buffer += len;
 
   // Verify various attributes of the archive, plus initialize the
   // shared string/symbol tables
@@ -2027,7 +1975,7 @@
   if (PrintSharedArchiveAndExit) {
     if (PrintSharedDictionary) {
       tty->print_cr("\nShared classes:\n");
-      SystemDictionary::print_shared(tty);
+      SystemDictionaryShared::print_on(tty);
     }
     if (_archive_loading_failed) {
       tty->print_cr("archive is invalid");