8145593: Clean up metaspaceShared.cpp
authoriklam
Mon, 04 Jan 2016 13:57:34 -0800
changeset 35231 e89989198037
parent 35230 a528ea8203ec
child 35232 76aed99c0ddd
child 35455 5c91d153e9da
child 35456 6dce879deda9
8145593: Clean up metaspaceShared.cpp Reviewed-by: jiangli
hotspot/src/share/vm/memory/filemap.hpp
hotspot/src/share/vm/memory/metaspace.cpp
hotspot/src/share/vm/memory/metaspaceShared.cpp
hotspot/src/share/vm/memory/metaspaceShared.hpp
--- a/hotspot/src/share/vm/memory/filemap.hpp	Mon Jan 04 11:38:42 2016 +0100
+++ b/hotspot/src/share/vm/memory/filemap.hpp	Mon Jan 04 13:57:34 2016 -0800
@@ -100,6 +100,7 @@
     Universe::NARROW_OOP_MODE _narrow_oop_mode; // compressed oop encoding mode
     int     _narrow_klass_shift;      // save narrow klass base and shift
     address _narrow_klass_base;
+    char*   _misc_data_patching_start;
 
     struct space_info {
       int    _crc;           // crc checksum of the current space
@@ -185,6 +186,8 @@
   int     narrow_klass_shift() const  { return _header->_narrow_klass_shift; }
   size_t space_capacity(int i)        { return _header->_space[i]._capacity; }
   struct FileMapHeader* header()      { return _header; }
+  char* misc_data_patching_start()            { return _header->_misc_data_patching_start; }
+  void set_misc_data_patching_start(char* p)  { _header->_misc_data_patching_start = p; }
 
   static FileMapInfo* current_info() {
     CDS_ONLY(return _current_info;)
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Mon Jan 04 11:38:42 2016 +0100
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Mon Jan 04 13:57:34 2016 -0800
@@ -421,7 +421,7 @@
       // Get a mmap region anywhere if the SharedBaseAddress fails.
       _rs = ReservedSpace(bytes, Metaspace::reserve_alignment(), large_pages);
     }
-    MetaspaceShared::set_shared_rs(&_rs);
+    MetaspaceShared::initialize_shared_rs(&_rs);
   } else
 #endif
   {
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Mon Jan 04 11:38:42 2016 +0100
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Mon Jan 04 13:57:34 2016 -0800
@@ -57,6 +57,48 @@
 bool MetaspaceShared::_check_classes_made_progress;
 bool MetaspaceShared::_has_error_classes;
 bool MetaspaceShared::_archive_loading_failed = false;
+SharedMiscRegion MetaspaceShared::_mc;
+SharedMiscRegion MetaspaceShared::_md;
+
+void SharedMiscRegion::initialize(ReservedSpace rs, size_t committed_byte_size,  SharedSpaceType space_type) {
+  _vs.initialize(rs, committed_byte_size);
+  _alloc_top = _vs.low();
+  _space_type = space_type;
+}
+
+// NOT thread-safe, but this is called during dump time in single-threaded mode.
+char* SharedMiscRegion::alloc(size_t num_bytes) {
+  assert(DumpSharedSpaces, "dump time only");
+  size_t alignment = sizeof(char*);
+  num_bytes = align_size_up(num_bytes, alignment);
+  _alloc_top = (char*)align_ptr_up(_alloc_top, alignment);
+  if (_alloc_top + num_bytes > _vs.high()) {
+    report_out_of_shared_space(_space_type);
+  }
+
+  char* p = _alloc_top;
+  _alloc_top += num_bytes;
+
+  memset(p, 0, num_bytes);
+  return p;
+}
+
+void MetaspaceShared::initialize_shared_rs(ReservedSpace* rs) {
+  assert(DumpSharedSpaces, "dump time only");
+  _shared_rs = rs;
+
+  // Split up and initialize the misc code and data spaces
+  size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
+  ReservedSpace shared_ro_rw = _shared_rs->first_part(metadata_size);
+  ReservedSpace misc_section = _shared_rs->last_part(metadata_size);
+
+  // Now split into misc sections.
+  ReservedSpace md_rs   = misc_section.first_part(SharedMiscDataSize);
+  ReservedSpace mc_rs   = misc_section.last_part(SharedMiscDataSize);
+  _md.initialize(md_rs, SharedMiscDataSize, SharedMiscData);
+  _mc.initialize(mc_rs, SharedMiscCodeSize, SharedMiscData);
+}
+
 // Read/write a data stream for restoring/preserving metadata pointers and
 // miscellaneous data from/to the shared archive file.
 
@@ -429,64 +471,17 @@
   VirtualSpace _mc_vs;
   CompactHashtableWriter* _string_cht;
   GrowableArray<MemRegion> *_string_regions;
-  char* _md_alloc_low;
-  char* _md_alloc_top;
-  char* _md_alloc_max;
-  static VM_PopulateDumpSharedSpace* _instance;
 
 public:
   VM_PopulateDumpSharedSpace(ClassLoaderData* loader_data,
                              GrowableArray<Klass*> *class_promote_order) :
     _loader_data(loader_data) {
-    // Split up and initialize the misc code and data spaces
-    ReservedSpace* shared_rs = MetaspaceShared::shared_rs();
-    size_t metadata_size = SharedReadOnlySize + SharedReadWriteSize;
-    ReservedSpace shared_ro_rw = shared_rs->first_part(metadata_size);
-    ReservedSpace misc_section = shared_rs->last_part(metadata_size);
-
-    // Now split into misc sections.
-    ReservedSpace md_rs   = misc_section.first_part(SharedMiscDataSize);
-    ReservedSpace mc_rs   = misc_section.last_part(SharedMiscDataSize);
-    _md_vs.initialize(md_rs, SharedMiscDataSize);
-    _mc_vs.initialize(mc_rs, SharedMiscCodeSize);
     _class_promote_order = class_promote_order;
-
-    _md_alloc_low = _md_vs.low();
-    _md_alloc_top = _md_alloc_low + sizeof(char*);
-    _md_alloc_max = _md_vs.low() + SharedMiscDataSize;
-
-    assert(_instance == NULL, "must be singleton");
-    _instance = this;
-  }
-
-  ~VM_PopulateDumpSharedSpace() {
-    assert(_instance == this, "must be singleton");
-    _instance = NULL;
-  }
-
-  static VM_PopulateDumpSharedSpace* instance() {
-    assert(_instance != NULL, "sanity");
-    return _instance;
   }
 
   VMOp_Type type() const { return VMOp_PopulateDumpSharedSpace; }
   void doit();   // outline because gdb sucks
 
-  char* misc_data_space_alloc(size_t num_bytes) {
-    size_t alignment = sizeof(char*);
-    num_bytes = align_size_up(num_bytes, alignment);
-    _md_alloc_top = (char*)align_ptr_up(_md_alloc_top, alignment);
-    if (_md_alloc_top + num_bytes > _md_alloc_max) {
-      report_out_of_shared_space(SharedMiscData);
-    }
-
-    char* p = _md_alloc_top;
-    _md_alloc_top += num_bytes;
-
-    memset(p, 0, num_bytes);
-    return p;
-  }
-
 private:
   void handle_misc_data_space_failure(bool success) {
     if (!success) {
@@ -495,8 +490,6 @@
   }
 }; // class VM_PopulateDumpSharedSpace
 
-VM_PopulateDumpSharedSpace* VM_PopulateDumpSharedSpace::_instance;
-
 void VM_PopulateDumpSharedSpace::doit() {
   Thread* THREAD = VMThread::vm_thread();
   NOT_PRODUCT(SystemDictionary::verify();)
@@ -555,17 +548,15 @@
   tty->print_cr("done. ");
 
   // Set up the share data and shared code segments.
+  _md_vs = *MetaspaceShared::misc_data_region()->virtual_space();
+  _mc_vs = *MetaspaceShared::misc_code_region()->virtual_space();
   char* md_low = _md_vs.low();
-  char* md_top = md_low;
+  char* md_top = MetaspaceShared::misc_data_region()->alloc_top();
   char* md_end = _md_vs.high();
   char* mc_low = _mc_vs.low();
-  char* mc_top = mc_low;
+  char* mc_top = MetaspaceShared::misc_code_region()->alloc_top();
   char* mc_end = _mc_vs.high();
 
-  assert(_md_alloc_top != NULL, "sanity");
-  *(char**)_md_alloc_low = _md_alloc_top;
-  md_top = _md_alloc_top;
-
   // Reserve space for the list of Klass*s whose vtables are used
   // for patching others as needed.
 
@@ -681,36 +672,32 @@
 
   FileMapInfo* mapinfo = new FileMapInfo();
   mapinfo->populate_header(MetaspaceShared::max_alignment());
-
-  // Pass 1 - update file offsets in header.
-  mapinfo->write_header();
-  mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true);
-  mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false);
-  mapinfo->write_region(MetaspaceShared::md, _md_vs.low(),
-                        pointer_delta(md_top, _md_vs.low(), sizeof(char)),
-                        SharedMiscDataSize,
-                        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->set_misc_data_patching_start((char*)vtbl_list);
 
-  // Pass 2 - write data.
-  mapinfo->open_for_write();
-  mapinfo->set_header_crc(mapinfo->compute_header_crc());
-  mapinfo->write_header();
-  mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true);
-  mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false);
-  mapinfo->write_region(MetaspaceShared::md, _md_vs.low(),
-                        pointer_delta(md_top, _md_vs.low(), sizeof(char)),
-                        SharedMiscDataSize,
-                        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);
+  for (int pass=1; pass<=2; pass++) {
+    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.
+    } else {
+      // After the first pass, the contents of mapinfo->_header are finalized,
+      // so we can compute the header's CRC, and write the contents of the header
+      // and the regions into disk.
+      mapinfo->open_for_write();
+      mapinfo->set_header_crc(mapinfo->compute_header_crc());
+    }
+    mapinfo->write_header();
+    mapinfo->write_space(MetaspaceShared::ro, _loader_data->ro_metaspace(), true);
+    mapinfo->write_space(MetaspaceShared::rw, _loader_data->rw_metaspace(), false);
+    mapinfo->write_region(MetaspaceShared::md, _md_vs.low(),
+                          pointer_delta(md_top, _md_vs.low(), sizeof(char)),
+                          SharedMiscDataSize,
+                          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();
 
@@ -938,11 +925,6 @@
   }
 }
 
-// Allocate misc data blocks during dumping.
-char* MetaspaceShared::misc_data_space_alloc(size_t num_bytes) {
-  return VM_PopulateDumpSharedSpace::instance()->misc_data_space_alloc(num_bytes);
-}
-
 // Closure for serializing initialization data in from a data area
 // (ptr_array) read from the shared file.
 
@@ -1065,10 +1047,7 @@
 
 void MetaspaceShared::initialize_shared_spaces() {
   FileMapInfo *mapinfo = FileMapInfo::current_info();
-
-  char* buffer = mapinfo->header()->region_addr(md);
-
-  buffer = *((char**)buffer); // skip over the md_alloc'ed blocks
+  char* buffer = mapinfo->misc_data_patching_start();
 
   // Skip over (reserve space for) a list of addresses of C++ vtables
   // for Klass objects.  They get filled in later.
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp	Mon Jan 04 11:38:42 2016 +0100
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp	Mon Jan 04 13:57:34 2016 -0800
@@ -97,6 +97,26 @@
   CompactHashtableStats string;
 };
 
+class SharedMiscRegion VALUE_OBJ_CLASS_SPEC {
+private:
+  VirtualSpace _vs;
+  char* _alloc_top;
+  SharedSpaceType _space_type;
+
+public:
+  void initialize(ReservedSpace rs, size_t committed_byte_size,  SharedSpaceType space_type);
+  VirtualSpace* virtual_space() {
+    return &_vs;
+  }
+  char* low() const {
+    return _vs.low();
+  }
+  char* alloc_top() const {
+    return _alloc_top;
+  }
+  char* alloc(size_t num_bytes) NOT_CDS_RETURN_(NULL);
+};
+
 // Class Data Sharing Support
 class MetaspaceShared : AllStatic {
 
@@ -108,6 +128,10 @@
   static bool _check_classes_made_progress;
   static bool _has_error_classes;
   static bool _archive_loading_failed;
+
+  // Used only during dumping.
+  static SharedMiscRegion _md;
+  static SharedMiscRegion _mc;
  public:
   enum {
     vtbl_list_size         = DEFAULT_VTBL_LIST_SIZE,
@@ -149,9 +173,7 @@
     NOT_CDS(return NULL);
   }
 
-  static void set_shared_rs(ReservedSpace* rs) {
-    CDS_ONLY(_shared_rs = rs;)
-  }
+  static void initialize_shared_rs(ReservedSpace* rs) NOT_CDS_RETURN;
 
   static void set_archive_loading_failed() {
     _archive_loading_failed = true;
@@ -191,7 +213,17 @@
   static int count_class(const char* classlist_file);
   static void estimate_regions_size() NOT_CDS_RETURN;
 
-  // Allocate a block of memory from the "md" region.
-  static char* misc_data_space_alloc(size_t num_bytes);
+  // Allocate a block of memory from the "mc" or "md" regions.
+  static char* misc_code_space_alloc(size_t num_bytes) {  return _mc.alloc(num_bytes); }
+  static char* misc_data_space_alloc(size_t num_bytes) {  return _md.alloc(num_bytes); }
+
+  static SharedMiscRegion* misc_code_region() {
+    assert(DumpSharedSpaces, "used during dumping only");
+    return &_mc;
+  }
+  static SharedMiscRegion* misc_data_region() {
+    assert(DumpSharedSpaces, "used during dumping only");
+    return &_md;
+  }
 };
 #endif // SHARE_VM_MEMORY_METASPACESHARED_HPP