src/hotspot/share/memory/metaspaceShared.cpp
changeset 49329 04ed29f9ef33
parent 48962 88ad6c676c87
child 49332 cd21aff24069
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Fri Mar 02 10:42:32 2018 -0800
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Fri Mar 02 17:25:55 2018 -0500
@@ -375,9 +375,45 @@
   StringTable::serialize(soc);
   soc->do_tag(--tag);
 
+  serialize_well_known_classes(soc);
+  soc->do_tag(--tag);
+
   soc->do_tag(666);
 }
 
+void MetaspaceShared::serialize_well_known_classes(SerializeClosure* soc) {
+  java_lang_Class::serialize(soc);
+  java_lang_String::serialize(soc);
+  java_lang_System::serialize(soc);
+  java_lang_ClassLoader::serialize(soc);
+  java_lang_Throwable::serialize(soc);
+  java_lang_Thread::serialize(soc);
+  java_lang_ThreadGroup::serialize(soc);
+  java_lang_AssertionStatusDirectives::serialize(soc);
+  java_lang_ref_SoftReference::serialize(soc);
+  java_lang_invoke_MethodHandle::serialize(soc);
+  java_lang_invoke_DirectMethodHandle::serialize(soc);
+  java_lang_invoke_MemberName::serialize(soc);
+  java_lang_invoke_ResolvedMethodName::serialize(soc);
+  java_lang_invoke_LambdaForm::serialize(soc);
+  java_lang_invoke_MethodType::serialize(soc);
+  java_lang_invoke_CallSite::serialize(soc);
+  java_lang_invoke_MethodHandleNatives_CallSiteContext::serialize(soc);
+  java_security_AccessControlContext::serialize(soc);
+  java_lang_reflect_AccessibleObject::serialize(soc);
+  java_lang_reflect_Method::serialize(soc);
+  java_lang_reflect_Constructor::serialize(soc);
+  java_lang_reflect_Field::serialize(soc);
+  java_nio_Buffer::serialize(soc);
+  reflect_ConstantPool::serialize(soc);
+  reflect_UnsafeStaticFieldAccessorImpl::serialize(soc);
+  java_lang_reflect_Parameter::serialize(soc);
+  java_lang_Module::serialize(soc);
+  java_lang_StackTraceElement::serialize(soc);
+  java_lang_StackFrameInfo::serialize(soc);
+  java_lang_LiveStackFrameInfo::serialize(soc);
+}
+
 address MetaspaceShared::cds_i2i_entry_code_buffers(size_t total_size) {
   if (DumpSharedSpaces) {
     if (_cds_i2i_entry_code_buffers == NULL) {
@@ -415,7 +451,12 @@
 class CollectClassesClosure : public KlassClosure {
   void do_klass(Klass* k) {
     if (!(k->is_instance_klass() && InstanceKlass::cast(k)->is_in_error_state())) {
-      _global_klass_objects->append_if_missing(k);
+      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_array_klass()) {
       // Add in the array classes too
@@ -452,6 +493,19 @@
   }
 }
 
+static void clear_basic_type_mirrors() {
+  assert(!MetaspaceShared::is_heap_object_archiving_allowed(), "Sanity");
+  Universe::set_int_mirror(NULL);
+  Universe::set_float_mirror(NULL);
+  Universe::set_double_mirror(NULL);
+  Universe::set_byte_mirror(NULL);
+  Universe::set_bool_mirror(NULL);
+  Universe::set_char_mirror(NULL);
+  Universe::set_long_mirror(NULL);
+  Universe::set_short_mirror(NULL);
+  Universe::set_void_mirror(NULL);
+}
+
 static void rewrite_nofast_bytecode(Method* method) {
   BytecodeStream bcs(method);
   while (!bcs.is_last_bytecode()) {
@@ -775,6 +829,17 @@
     _dump_region->append_intptr_t((intptr_t)tag);
   }
 
+  void do_oop(oop* o) {
+    if (*o == NULL) {
+      _dump_region->append_intptr_t(0);
+    } else {
+      assert(MetaspaceShared::is_heap_object_archiving_allowed(),
+             "Archiving heap object is not allowed");
+      _dump_region->append_intptr_t(
+        (intptr_t)oopDesc::encode_heap_oop_not_null(*o));
+    }
+  }
+
   void do_region(u_char* start, size_t size) {
     assert((intptr_t)start % sizeof(intptr_t) == 0, "bad alignment");
     assert(size % sizeof(intptr_t) == 0, "bad size");
@@ -935,7 +1000,7 @@
 
 class VM_PopulateDumpSharedSpace: public VM_Operation {
 private:
-  GrowableArray<MemRegion> *_string_regions;
+  GrowableArray<MemRegion> *_closed_archive_heap_regions;
   GrowableArray<MemRegion> *_open_archive_heap_regions;
 
   void dump_java_heap_objects() NOT_CDS_JAVA_HEAP_RETURN;
@@ -1193,6 +1258,7 @@
   }
 
   static Klass* get_relocated_klass(Klass* orig_klass) {
+    assert(DumpSharedSpaces, "dump time only");
     address* pp = _new_loc_table->get((address)orig_klass);
     assert(pp != NULL, "must be");
     Klass* klass = (Klass*)(*pp);
@@ -1222,7 +1288,11 @@
   // 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 (!MetaspaceShared::is_heap_object_archiving_allowed()) {
+    clear_basic_type_mirrors();
+  }
   remove_java_mirror_in_classes();
   tty->print_cr("done. ");
   NOT_PRODUCT(SystemDictionary::verify();)
@@ -1312,7 +1382,7 @@
   dump_symbols();
 
   // Dump supported java heap objects
-  _string_regions = NULL;
+  _closed_archive_heap_regions = NULL;
   _open_archive_heap_regions = NULL;
   dump_java_heap_objects();
 
@@ -1375,7 +1445,7 @@
     write_region(mapinfo, MetaspaceShared::od, &_od_region, /*read_only=*/true, /*allow_exec=*/false);
 
     _total_string_region_size = mapinfo->write_archive_heap_regions(
-                                        _string_regions,
+                                        _closed_archive_heap_regions,
                                         MetaspaceShared::first_string,
                                         MetaspaceShared::max_strings);
     _total_open_archive_region_size = mapinfo->write_archive_heap_regions(
@@ -1424,7 +1494,7 @@
   _ro_region.print(total_reserved);
   _md_region.print(total_reserved);
   _od_region.print(total_reserved);
-  print_heap_region_stats(_string_regions, "st", total_reserved);
+  print_heap_region_stats(_closed_archive_heap_regions, "st", total_reserved);
   print_heap_region_stats(_open_archive_heap_regions, "oa", total_reserved);
 
   tty->print_cr("total    : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]",
@@ -1452,6 +1522,11 @@
   o->set_klass(k);
 }
 
+Klass* MetaspaceShared::get_relocated_klass(Klass *k) {
+  assert(DumpSharedSpaces, "sanity");
+  return ArchiveCompactor::get_relocated_klass(k);
+}
+
 class LinkSharedClassesClosure : public KlassClosure {
   Thread* THREAD;
   bool    _made_progress;
@@ -1693,11 +1768,11 @@
     // Cache for recording where the archived objects are copied to
     MetaspaceShared::create_archive_object_cache();
 
-    tty->print_cr("Dumping String objects to closed archive heap region ...");
+    tty->print_cr("Dumping objects to closed archive heap region ...");
     NOT_PRODUCT(StringTable::verify());
-    // The string space has maximum two regions. See FileMapInfo::write_archive_heap_regions() for details.
-    _string_regions = new GrowableArray<MemRegion>(2);
-    StringTable::write_to_archive(_string_regions);
+    // The closed space has maximum two regions. See FileMapInfo::write_archive_heap_regions() for details.
+    _closed_archive_heap_regions = new GrowableArray<MemRegion>(2);
+    MetaspaceShared::dump_closed_archive_heap_objects(_closed_archive_heap_regions);
 
     tty->print_cr("Dumping objects to open archive heap region ...");
     _open_archive_heap_regions = new GrowableArray<MemRegion>(2);
@@ -1709,6 +1784,20 @@
   G1HeapVerifier::verify_archive_regions();
 }
 
+void MetaspaceShared::dump_closed_archive_heap_objects(
+                                    GrowableArray<MemRegion> * closed_archive) {
+  assert(is_heap_object_archiving_allowed(), "Cannot dump java heap objects");
+
+  Thread* THREAD = Thread::current();
+  G1CollectedHeap::heap()->begin_archive_alloc_range();
+
+  // Archive interned string objects
+  StringTable::write_to_archive(closed_archive);
+
+  G1CollectedHeap::heap()->end_archive_alloc_range(closed_archive,
+                                                   os::vm_allocation_granularity());
+}
+
 void MetaspaceShared::dump_open_archive_heap_objects(
                                     GrowableArray<MemRegion> * open_archive) {
   assert(UseG1GC, "Only support G1 GC");
@@ -1718,21 +1807,33 @@
   Thread* THREAD = Thread::current();
   G1CollectedHeap::heap()->begin_archive_alloc_range(true /* open */);
 
-  MetaspaceShared::archive_resolved_constants(THREAD);
+  java_lang_Class::archive_basic_type_mirrors(THREAD);
+
+  MetaspaceShared::archive_klass_objects(THREAD);
 
   G1CollectedHeap::heap()->end_archive_alloc_range(open_archive,
                                                    os::vm_allocation_granularity());
 }
 
 MetaspaceShared::ArchivedObjectCache* MetaspaceShared::_archive_object_cache = NULL;
+oop MetaspaceShared::find_archived_heap_object(oop obj) {
+  assert(DumpSharedSpaces, "dump-time only");
+  ArchivedObjectCache* cache = MetaspaceShared::archive_object_cache();
+  oop* p = cache->get(obj);
+  if (p != NULL) {
+    return *p;
+  } else {
+    return NULL;
+  }
+}
+
 oop MetaspaceShared::archive_heap_object(oop obj, Thread* THREAD) {
   assert(DumpSharedSpaces, "dump-time only");
 
-  ArchivedObjectCache* cache = MetaspaceShared::archive_object_cache();
-  oop* p = cache->get(obj);
-  if (p != NULL) {
+  oop ao = find_archived_heap_object(obj);
+  if (ao != NULL) {
     // already archived
-    return *p;
+    return ao;
   }
 
   int len = obj->size();
@@ -1745,15 +1846,23 @@
   if (archived_oop != NULL) {
     Copy::aligned_disjoint_words((HeapWord*)obj, (HeapWord*)archived_oop, len);
     relocate_klass_ptr(archived_oop);
+    ArchivedObjectCache* cache = MetaspaceShared::archive_object_cache();
     cache->put(obj, archived_oop);
   }
+  log_debug(cds)("Archived heap object " PTR_FORMAT " ==> " PTR_FORMAT,
+                 p2i(obj), p2i(archived_oop));
   return archived_oop;
 }
 
-void MetaspaceShared::archive_resolved_constants(Thread* THREAD) {
+void MetaspaceShared::archive_klass_objects(Thread* THREAD) {
   int i;
   for (i = 0; i < _global_klass_objects->length(); i++) {
     Klass* k = _global_klass_objects->at(i);
+
+    // archive mirror object
+    java_lang_Class::archive_mirror(k, CHECK);
+
+    // archive the resolved_referenes array
     if (k->is_instance_klass()) {
       InstanceKlass* ik = InstanceKlass::cast(k);
       ik->constants()->archive_resolved_references(THREAD);
@@ -1802,6 +1911,19 @@
     FileMapInfo::assert_mark(tag == old_tag);
   }
 
+  void do_oop(oop *p) {
+    narrowOop o = (narrowOop)nextPtr();
+    if (o == 0 || !MetaspaceShared::open_archive_heap_region_mapped()) {
+      p = NULL;
+    } else {
+      assert(MetaspaceShared::is_heap_object_archiving_allowed(),
+             "Archived heap object is not allowed");
+      assert(MetaspaceShared::open_archive_heap_region_mapped(),
+             "Open archive heap region is not mapped");
+      RootAccess<IN_ARCHIVE_ROOT>::oop_store(p, oopDesc::decode_heap_oop_not_null(o));
+    }
+  }
+
   void do_region(u_char* start, size_t size) {
     assert((intptr_t)start % sizeof(intptr_t) == 0, "bad alignment");
     assert(size % sizeof(intptr_t) == 0, "bad size");