hotspot/src/share/vm/memory/metaspaceShared.cpp
changeset 37995 92aec042a43b
parent 37439 e8970711113b
child 38151 fffedc5e5cf8
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Tue Apr 19 11:03:37 2016 -0400
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Sun Apr 17 19:15:52 2016 -0700
@@ -31,6 +31,7 @@
 #include "classfile/sharedClassUtil.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "classfile/systemDictionaryShared.hpp"
 #include "code/codeCache.hpp"
 #include "gc/shared/gcLocker.hpp"
 #include "interpreter/bytecodeStream.hpp"
@@ -106,7 +107,8 @@
 // Read/write a data stream for restoring/preserving metadata pointers and
 // miscellaneous data from/to the shared archive file.
 
-void MetaspaceShared::serialize(SerializeClosure* soc) {
+void MetaspaceShared::serialize(SerializeClosure* soc, GrowableArray<MemRegion> *string_space,
+                                size_t* space_size) {
   int tag = 0;
   soc->do_tag(--tag);
 
@@ -128,6 +130,15 @@
   vmSymbols::serialize(soc);
   soc->do_tag(--tag);
 
+  // Dump/restore the symbol and string tables
+  SymbolTable::serialize(soc);
+  StringTable::serialize(soc, string_space, space_size);
+  soc->do_tag(--tag);
+
+  // Dump/restore the misc information for system dictionary
+  SystemDictionaryShared::serialize(soc);
+  soc->do_tag(--tag);
+
   soc->do_tag(666);
 }
 
@@ -314,6 +325,11 @@
     ++top;
   }
 
+  void do_u4(u4* p) {
+    void* ptr = (void*)(uintx(*p));
+    do_ptr(&ptr);
+  }
+
   void do_tag(int tag) {
     check_space();
     *top = (intptr_t)tag;
@@ -348,6 +364,8 @@
   METASPACE_OBJ_TYPES_DO(f) \
   f(SymbolHashentry) \
   f(SymbolBucket) \
+  f(StringHashentry) \
+  f(StringBucket) \
   f(Other)
 
 #define SHAREDSPACE_OBJ_TYPE_DECLARE(name) name ## Type,
@@ -406,13 +424,22 @@
   MetaspaceSharedStats *stats = MetaspaceShared::stats();
 
   // symbols
-  _counts[RW][SymbolHashentryType] = stats->symbol.hashentry_count;
-  _bytes [RW][SymbolHashentryType] = stats->symbol.hashentry_bytes;
-  other_bytes -= stats->symbol.hashentry_bytes;
+  _counts[RO][SymbolHashentryType] = stats->symbol.hashentry_count;
+  _bytes [RO][SymbolHashentryType] = stats->symbol.hashentry_bytes;
+  _bytes [RO][TypeArrayU4Type]    -= stats->symbol.hashentry_bytes;
+
+  _counts[RO][SymbolBucketType] = stats->symbol.bucket_count;
+  _bytes [RO][SymbolBucketType] = stats->symbol.bucket_bytes;
+  _bytes [RO][TypeArrayU4Type] -= stats->symbol.bucket_bytes;
 
-  _counts[RW][SymbolBucketType] = stats->symbol.bucket_count;
-  _bytes [RW][SymbolBucketType] = stats->symbol.bucket_bytes;
-  other_bytes -= stats->symbol.bucket_bytes;
+  // strings
+  _counts[RO][StringHashentryType] = stats->string.hashentry_count;
+  _bytes [RO][StringHashentryType] = stats->string.hashentry_bytes;
+  _bytes [RO][TypeArrayU4Type]    -= stats->string.hashentry_bytes;
+
+  _counts[RO][StringBucketType] = stats->string.bucket_count;
+  _bytes [RO][StringBucketType] = stats->string.bucket_bytes;
+  _bytes [RO][TypeArrayU4Type] -= stats->string.bucket_bytes;
 
   // TODO: count things like dictionary, vtable, etc
   _bytes[RW][OtherType] =  other_bytes;
@@ -488,7 +515,6 @@
   GrowableArray<Klass*> *_class_promote_order;
   VirtualSpace _md_vs;
   VirtualSpace _mc_vs;
-  CompactHashtableWriter* _string_cht;
   GrowableArray<MemRegion> *_string_regions;
 
 public:
@@ -600,39 +626,27 @@
   // Not doing this either.
 
   SystemDictionary::reorder_dictionary();
-
   NOT_PRODUCT(SystemDictionary::verify();)
-
-  // Copy the symbol table, string table, and the system dictionary to the shared
-  // space in usable form.  Copy the hashtable
-  // buckets first [read-write], then copy the linked lists of entries
-  // [read-only].
-
-  NOT_PRODUCT(SymbolTable::verify());
-  handle_misc_data_space_failure(SymbolTable::copy_compact_table(&md_top, md_end));
-
-  size_t ss_bytes = 0;
-  char* ss_low;
-  // The string space has maximum two regions. See FileMapInfo::write_string_regions() for details.
-  _string_regions = new GrowableArray<MemRegion>(2);
-  NOT_PRODUCT(StringTable::verify());
-  handle_misc_data_space_failure(StringTable::copy_compact_table(&md_top, md_end, _string_regions,
-                                                                 &ss_bytes));
-  ss_low = _string_regions->is_empty() ? NULL : (char*)_string_regions->first().start();
-
   SystemDictionary::reverse();
   SystemDictionary::copy_buckets(&md_top, md_end);
 
   SystemDictionary::copy_table(&md_top, md_end);
 
   // Write the other data to the output array.
+  // SymbolTable, StringTable and extra information for system dictionary
+  NOT_PRODUCT(SymbolTable::verify());
+  NOT_PRODUCT(StringTable::verify());
+  size_t ss_bytes = 0;
+  char* ss_low;
+  // The string space has maximum two regions. See FileMapInfo::write_string_regions() for details.
+  _string_regions = new GrowableArray<MemRegion>(2);
+
   WriteClosure wc(md_top, md_end);
-  MetaspaceShared::serialize(&wc);
+  MetaspaceShared::serialize(&wc, _string_regions, &ss_bytes);
   md_top = wc.get_top();
+  ss_low = _string_regions->is_empty() ? NULL : (char*)_string_regions->first().start();
 
   // Print shared spaces all the time
-// To make fmt_space be a syntactic constant (for format warnings), use #define.
-#define fmt_space "%s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%4.1f%% used] at " INTPTR_FORMAT
   Metaspace* ro_space = _loader_data->ro_metaspace();
   Metaspace* rw_space = _loader_data->rw_metaspace();
 
@@ -665,12 +679,13 @@
   const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0;
   const double total_u_perc = total_bytes / double(total_alloced) * 100.0;
 
+#define fmt_space "%s space: " SIZE_FORMAT_W(9) " [ %4.1f%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used] at " INTPTR_FORMAT
   tty->print_cr(fmt_space, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, p2i(ro_space->bottom()));
   tty->print_cr(fmt_space, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, p2i(rw_space->bottom()));
   tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, p2i(md_low));
   tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, p2i(mc_low));
   tty->print_cr(fmt_space, "st", ss_bytes, ss_t_perc, ss_bytes,   100.0,     p2i(ss_low));
-  tty->print_cr("total   : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%4.1f%% used]",
+  tty->print_cr("total   : " SIZE_FORMAT_W(9) " [100.0%% of total] out of " SIZE_FORMAT_W(9) " bytes [%5.1f%% used]",
                  total_bytes, total_alloced, total_u_perc);
 
   // Update the vtable pointers in all of the Klass objects in the
@@ -974,6 +989,11 @@
     *p = (void*)obj;
   }
 
+  void do_u4(u4* p) {
+    intptr_t obj = nextPtr();
+    *p = (u4)(uintx(obj));
+  }
+
   void do_tag(int tag) {
     int old_tag;
     old_tag = (int)(intptr_t)nextPtr();
@@ -1097,21 +1117,6 @@
   buffer += sizeof(intptr_t);
   buffer += vtable_size;
 
-  // Create the shared symbol table using the compact table at this spot in the
-  // misc data space. (Todo: move this to read-only space. Currently
-  // this is mapped copy-on-write but will never be written into).
-
-  buffer = (char*)SymbolTable::init_shared_table(buffer);
-  SymbolTable::create_table();
-
-  // Create the shared string table using the compact table
-  buffer = (char*)StringTable::init_shared_table(mapinfo, buffer);
-
-  // Create the shared dictionary using the bucket array at this spot in
-  // the misc data space.  Since the shared dictionary table is never
-  // modified, this region (of mapped pages) will be (effectively, if
-  // not explicitly) read-only.
-
   int sharedDictionaryLen = *(intptr_t*)buffer;
   buffer += sizeof(intptr_t);
   int number_of_entries = *(intptr_t*)buffer;
@@ -1129,9 +1134,14 @@
   buffer += sizeof(intptr_t);
   buffer += len;
 
+  // Verify various attributes of the archive, plus initialize the
+  // shared string/symbol tables
   intptr_t* array = (intptr_t*)buffer;
   ReadClosure rc(&array);
-  serialize(&rc);
+  serialize(&rc, NULL, NULL);
+
+  // Initialize the run-time symbol table.
+  SymbolTable::create_table();
 
   // Close the mapinfo file
   mapinfo->close();