< prev index next >

src/share/vm/memory/metaspaceShared.cpp

Print this page

        

@@ -420,10 +420,12 @@
 private:
   ClassLoaderData* _loader_data;
   GrowableArray<Klass*> *_class_promote_order;
   VirtualSpace _md_vs;
   VirtualSpace _mc_vs;
+  CompactHashtableWriter* _string_cht;
+  GrowableArray<MemRegion> *_string_regions;
 
 public:
   VM_PopulateDumpSharedSpace(ClassLoaderData* loader_data,
                              GrowableArray<Klass*> *class_promote_order) :
     _loader_data(loader_data) {

@@ -538,18 +540,27 @@
 
   SystemDictionary::reorder_dictionary();
 
   NOT_PRODUCT(SystemDictionary::verify();)
 
-  // Copy the the symbol table, and the system dictionary to the shared
+  // Copy the 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);
 
   ClassLoader::verify();
   ClassLoader::copy_package_info_buckets(&md_top, md_end);

@@ -574,24 +585,26 @@
   // Allocated size of each space (may not be all occupied)
   const size_t ro_alloced = ro_space->capacity_bytes_slow(Metaspace::NonClassType);
   const size_t rw_alloced = rw_space->capacity_bytes_slow(Metaspace::NonClassType);
   const size_t md_alloced = md_end-md_low;
   const size_t mc_alloced = mc_end-mc_low;
-  const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced;
+  const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced
+                             + ss_bytes;
 
   // Occupied size of each space.
   const size_t ro_bytes = ro_space->used_bytes_slow(Metaspace::NonClassType);
   const size_t rw_bytes = rw_space->used_bytes_slow(Metaspace::NonClassType);
   const size_t md_bytes = size_t(md_top - md_low);
   const size_t mc_bytes = size_t(mc_top - mc_low);
 
   // Percent of total size
-  const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes;
+  const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes + ss_bytes;
   const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0;
   const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0;
   const double md_t_perc = md_bytes / double(total_bytes) * 100.0;
   const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0;
+  const double ss_t_perc = ss_bytes / double(total_bytes) * 100.0;
 
   // Percent of fullness of each space
   const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0;
   const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0;
   const double md_u_perc = md_bytes / double(md_alloced) * 100.0;

@@ -600,10 +613,11 @@
 
   tty->print_cr(fmt_space, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom());
   tty->print_cr(fmt_space, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom());
   tty->print_cr(fmt_space, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low);
   tty->print_cr(fmt_space, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low);
+  tty->print_cr(fmt_space, "st", ss_bytes, ss_t_perc, ss_bytes, 100.0, ss_low);
   tty->print_cr("total   : %9d [100.0%% of total] out of %9d bytes [%4.1f%% used]",
                  total_bytes, total_alloced, total_u_perc);
 
   // Update the vtable pointers in all of the Klass objects in the
   // heap. They should point to newly generated vtable.

@@ -629,10 +643,11 @@
                         false, false);
   mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(),
                         pointer_delta(mc_top, _mc_vs.low(), sizeof(char)),
                         SharedMiscCodeSize,
                         true, true);
+  mapinfo->write_string_regions(_string_regions);
 
   // Pass 2 - write data.
   mapinfo->open_for_write();
   mapinfo->set_header_crc(mapinfo->compute_header_crc());
   mapinfo->write_header();

@@ -644,10 +659,12 @@
                         false, false);
   mapinfo->write_region(MetaspaceShared::mc, _mc_vs.low(),
                         pointer_delta(mc_top, _mc_vs.low(), sizeof(char)),
                         SharedMiscCodeSize,
                         true, true);
+  mapinfo->write_string_regions(_string_regions);
+  
   mapinfo->close();
 
   memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*));
   os::free(saved_vtbl);
 

@@ -940,10 +957,15 @@
 // Return true if given address is in the mapped shared space.
 bool MetaspaceShared::is_in_shared_space(const void* p) {
   return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_space(p);
 }
 
+bool MetaspaceShared::is_string_region(int idx) {
+  return (idx >= MetaspaceShared::first_string &&
+          idx < MetaspaceShared::first_string + MetaspaceShared::max_strings);
+}
+
 void MetaspaceShared::print_shared_spaces() {
   if (UseSharedSpaces) {
     FileMapInfo::current_info()->print_shared_spaces();
   }
 }

@@ -977,10 +999,12 @@
        mapinfo->verify_region_checksum(rw) &&
       (_md_base = mapinfo->map_region(md)) != NULL &&
        mapinfo->verify_region_checksum(md) &&
       (_mc_base = mapinfo->map_region(mc)) != NULL &&
        mapinfo->verify_region_checksum(mc) &&
+      mapinfo->map_string_regions() &&
+      mapinfo->verify_string_regions() &&
       (image_alignment == (size_t)max_alignment()) &&
       mapinfo->validate_classpath_entry_table()) {
     // Success (no need to do anything)
     return true;
   } else {

@@ -988,10 +1012,11 @@
     // that succeeded
     if (_ro_base != NULL) mapinfo->unmap_region(ro);
     if (_rw_base != NULL) mapinfo->unmap_region(rw);
     if (_md_base != NULL) mapinfo->unmap_region(md);
     if (_mc_base != NULL) mapinfo->unmap_region(mc);
+    mapinfo->unmap_string_regions();
 #ifndef _WINDOWS
     // Release the entire mapped region
     shared_rs.release();
 #endif
     // If -Xshare:on is specified, print out the error message and exit VM,

@@ -1009,11 +1034,11 @@
 // serialize it out to its various destinations.
 
 void MetaspaceShared::initialize_shared_spaces() {
   FileMapInfo *mapinfo = FileMapInfo::current_info();
 
-  char* buffer = mapinfo->region_base(md);
+  char* buffer = mapinfo->header()->region_addr(md);
 
   // Skip over (reserve space for) a list of addresses of C++ vtables
   // for Klass objects.  They get filled in later.
 
   void** vtbl_list = (void**)buffer;

@@ -1025,17 +1050,20 @@
 
   intptr_t vtable_size = *(intptr_t*)buffer;
   buffer += sizeof(intptr_t);
   buffer += vtable_size;
 
-  // Create the shared symbol table using the bucket array at this spot in the
+  // 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.
 

@@ -1098,10 +1126,15 @@
       vm_exit(0);
     }
   }
 }
 
+void MetaspaceShared::fixup_shared_string_regions() {
+  FileMapInfo *mapinfo = FileMapInfo::current_info();
+  mapinfo->fixup_string_regions();
+}
+
 // JVM/TI RedefineClasses() support:
 bool MetaspaceShared::remap_shared_readonly_as_readwrite() {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 
   if (UseSharedSpaces) {
< prev index next >