changeset 56248:0d97bf7cf8a4

8230586: Encapsulate fields in filemap.hpp Reviewed-by: ccheung
author iklam
date Wed, 11 Sep 2019 18:31:25 -0700
parents adc72cd1d1f2
children fa0514bdc09b
files src/hotspot/share/classfile/classLoaderExt.cpp src/hotspot/share/classfile/systemDictionaryShared.cpp src/hotspot/share/include/cds.h src/hotspot/share/interpreter/abstractInterpreter.cpp src/hotspot/share/memory/dynamicArchive.cpp src/hotspot/share/memory/dynamicArchive.hpp src/hotspot/share/memory/filemap.cpp src/hotspot/share/memory/filemap.hpp src/hotspot/share/memory/metaspaceShared.cpp src/hotspot/share/memory/metaspaceShared.hpp src/hotspot/share/prims/cdsoffsets.cpp test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java
diffstat 12 files changed, 375 insertions(+), 253 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Wed Sep 11 18:31:25 2019 -0700
@@ -55,7 +55,7 @@
 void ClassLoaderExt::append_boot_classpath(ClassPathEntry* new_entry) {
   if (UseSharedSpaces) {
     warning("Sharing is only supported for boot loader classes because bootstrap classpath has been appended");
-    FileMapInfo::current_info()->header()->set_has_platform_or_app_classes(false);
+    FileMapInfo::current_info()->set_has_platform_or_app_classes(false);
   }
   ClassLoader::add_to_boot_append_entries(new_entry);
 }
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Wed Sep 11 18:31:25 2019 -0700
@@ -744,11 +744,11 @@
 }
 
 bool SystemDictionaryShared::has_platform_or_app_classes() {
-  if (FileMapInfo::current_info()->header()->has_platform_or_app_classes()) {
+  if (FileMapInfo::current_info()->has_platform_or_app_classes()) {
     return true;
   }
   if (DynamicArchive::is_mapped() &&
-      FileMapInfo::dynamic_info()->header()->has_platform_or_app_classes()) {
+      FileMapInfo::dynamic_info()->has_platform_or_app_classes()) {
     return true;
   }
   return false;
--- a/src/hotspot/share/include/cds.h	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/include/cds.h	Wed Sep 11 18:31:25 2019 -0700
@@ -36,22 +36,23 @@
 #define NUM_CDS_REGIONS 8 // this must be the same as MetaspaceShared::n_regions
 #define CDS_ARCHIVE_MAGIC 0xf00baba2
 #define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8
-#define CURRENT_CDS_ARCHIVE_VERSION 7
+#define CURRENT_CDS_ARCHIVE_VERSION 8
 #define INVALID_CDS_ARCHIVE_VERSION -1
 
 struct CDSFileMapRegion {
-  int        _crc;           // crc checksum of the current space
-  size_t     _file_offset;   // sizeof(this) rounded to vm page size
+  int        _crc;            // crc checksum of the current space
+  size_t     _file_offset;    // sizeof(this) rounded to vm page size
   union {
-    char*    _base;          // copy-on-write base address
-    size_t   _offset;        // offset from the compressed oop encoding base, only used
-                             // by archive heap space
+    char*    _base;           // copy-on-write base address
+    size_t   _offset;         // offset from the compressed oop encoding base, only used
+                              // by archive heap space
   } _addr;
-  size_t     _used;          // for setting space top on read
-  int        _read_only;     // read only space?
-  int        _allow_exec;    // executable code in space?
-  void*      _oopmap;        // bitmap for relocating embedded oops
+  size_t     _used;           // for setting space top on read
+  int        _read_only;      // read only space?
+  int        _allow_exec;     // executable code in space?
+  void*      _oopmap;         // bitmap for relocating embedded oops
   size_t     _oopmap_size_in_bits;
+  int        _is_heap_region; // used in debug build only.
 };
 
 struct CDSFileMapHeaderBase {
--- a/src/hotspot/share/interpreter/abstractInterpreter.cpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/interpreter/abstractInterpreter.cpp	Wed Sep 11 18:31:25 2019 -0700
@@ -208,7 +208,7 @@
 
 address AbstractInterpreter::get_trampoline_code_buffer(AbstractInterpreter::MethodKind kind) {
   const size_t trampoline_size = SharedRuntime::trampoline_size();
-  address addr = MetaspaceShared::cds_i2i_entry_code_buffers((size_t)(AbstractInterpreter::number_of_method_entries) * trampoline_size);
+  address addr = MetaspaceShared::i2i_entry_code_buffers((size_t)(AbstractInterpreter::number_of_method_entries) * trampoline_size);
   addr += (size_t)(kind) * trampoline_size;
 
   return addr;
--- a/src/hotspot/share/memory/dynamicArchive.cpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/memory/dynamicArchive.cpp	Wed Sep 11 18:31:25 2019 -0700
@@ -652,7 +652,7 @@
       it->push(&_symbols->at(i));
     }
 
-    _header->_shared_path_table.metaspace_pointers_do(it);
+    _header->shared_path_table_metaspace_pointers_do(it);
 
     // Do not call these again, as we have already collected all the classes and symbols
     // that we want to archive. Also, these calls would corrupt the tables when
@@ -733,14 +733,13 @@
   init_first_dump_space(reserved_bottom);
 
   FileMapInfo* mapinfo = new FileMapInfo(false);
-  _header = (DynamicArchiveHeader*)mapinfo->_header;
+  _header = mapinfo->dynamic_header();
 
   Thread* THREAD = Thread::current();
   FileMapInfo* base_info = FileMapInfo::current_info();
-  int* crc = _header->_base_archive_crc;
-  *crc++ = base_info->crc(); // base archive header crc
+  _header->set_base_header_crc(base_info->crc());
   for (int i = 0; i < MetaspaceShared::n_regions; i++) {
-    *crc++ = base_info->space_crc(i);
+    _header->set_base_region_crc(i, base_info->space_crc(i));
   }
   _header->populate(base_info, os::vm_allocation_granularity());
 }
@@ -907,9 +906,9 @@
   RelocateBufferToTarget patcher(this, (address*)_alloc_bottom, _buffer_to_target_delta);
   _ptrmap.iterate(&patcher);
 
-  Array<u8>* table = _header->_shared_path_table.table();
+  Array<u8>* table = _header->shared_path_table().table();
   table = to_target(table);
- _header->_shared_path_table.set_table(table);
+ _header->relocate_shared_path_table(table);
 }
 
 static void write_archive_info(FileMapInfo* dynamic_info, DynamicArchiveHeader *header) {
@@ -933,7 +932,7 @@
   int num_klasses = _klasses->length();
   int num_symbols = _symbols->length();
 
-  _header->_read_only_tables_start = to_target(read_only_tables_start);
+  _header->set_read_only_tables_start(to_target(read_only_tables_start));
 
   FileMapInfo* dynamic_info = FileMapInfo::dynamic_info();
   assert(dynamic_info != NULL, "Sanity");
@@ -953,10 +952,11 @@
 
   address base = to_target(_alloc_bottom);
   address top  = address(current_dump_space()->top()) + _buffer_to_target_delta;
-  int file_size = int(top - base);
+  size_t file_size = pointer_delta(top, base, sizeof(char));
 
-  log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT " [%d bytes header, %d bytes total]",
-                         p2i(base), p2i(top), (int)_header->_header_size, file_size);
+  log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT
+                         " [" SIZE_FORMAT " bytes header, " SIZE_FORMAT " bytes total]",
+                         p2i(base), p2i(top), _header->header_size(), file_size);
   log_info(cds, dynamic)("%d klasses; %d symbols", num_klasses, num_symbols);
 }
 
@@ -1046,8 +1046,8 @@
 DynamicArchiveBuilder* DynamicArchive::_builder = NULL;
 
 void DynamicArchive::map_failed(FileMapInfo* mapinfo) {
-  if (mapinfo->_header != NULL) {
-    os::free(mapinfo->_header);
+  if (mapinfo->dynamic_header() != NULL) {
+    os::free((void*)mapinfo->dynamic_header());
   }
   delete mapinfo;
 }
@@ -1081,15 +1081,12 @@
 }
 
 address DynamicArchive::map_impl(FileMapInfo* mapinfo) {
-
-
   // Read header
   if (!mapinfo->initialize(false)) {
     return NULL;
   }
 
-  _dynamic_header = (DynamicArchiveHeader*)mapinfo->header();
-
+  _dynamic_header = mapinfo->dynamic_header();
   int regions[] = {MetaspaceShared::rw,
                    MetaspaceShared::ro,
                    MetaspaceShared::mc};
@@ -1111,7 +1108,7 @@
     return NULL;
   }
 
-  intptr_t* buffer = (intptr_t*)_dynamic_header->_read_only_tables_start;
+  intptr_t* buffer = (intptr_t*)_dynamic_header->read_only_tables_start();
   ReadClosure rc(&buffer);
   SymbolTable::serialize_shared_table_header(&rc, false);
   SystemDictionaryShared::serialize_dictionary_headers(&rc, false);
@@ -1122,18 +1119,17 @@
 bool DynamicArchive::validate(FileMapInfo* dynamic_info) {
   // Check if the recorded base archive matches with the current one
   FileMapInfo* base_info = FileMapInfo::current_info();
-  DynamicArchiveHeader* dynamic_header = (DynamicArchiveHeader*)dynamic_info->header();
-  int* crc = dynamic_header->_base_archive_crc;
+  DynamicArchiveHeader* dynamic_header = dynamic_info->dynamic_header();
 
   // Check the header crc
-  if (*crc++ != base_info->crc()) {
+  if (dynamic_header->base_header_crc() != base_info->crc()) {
     FileMapInfo::fail_continue("Archive header checksum verification failed.");
     return false;
   }
 
   // Check each space's crc
   for (int i = 0; i < MetaspaceShared::n_regions; i++) {
-    if (*crc++ != base_info->space_crc(i)) {
+    if (dynamic_header->base_region_crc(i) != base_info->space_crc(i)) {
       FileMapInfo::fail_continue("Archive region #%d checksum verification failed.", i);
       return false;
     }
--- a/src/hotspot/share/memory/dynamicArchive.hpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/memory/dynamicArchive.hpp	Wed Sep 11 18:31:25 2019 -0700
@@ -37,12 +37,24 @@
 #include "utilities/macros.hpp"
 #include "utilities/resourceHash.hpp"
 
-// We want to include all archive header information in the dynamic archive.
-// This helps simplify the process if the base layer archive is missing at
-// dynamic archiving time.
-struct DynamicArchiveHeader : public FileMapHeader {
-  // crc for the base archive header and regions
-  int _base_archive_crc[MetaspaceShared::n_regions+1];
+class DynamicArchiveHeader : public FileMapHeader {
+  friend class CDSOffsets;
+private:
+  int _base_header_crc;
+  int _base_region_crc[MetaspaceShared::n_regions];
+
+public:
+  int base_header_crc() const { return _base_header_crc; }
+  int base_region_crc(int i) const {
+    assert(is_valid_region(i), "must be");
+    return _base_region_crc[i];
+  }
+
+  void set_base_header_crc(int c) { _base_header_crc = c; }
+  void set_base_region_crc(int i, int c) {
+    assert(is_valid_region(i), "must be");
+    _base_region_crc[i] = c;
+  }
 };
 
 class DynamicArchive : AllStatic {
--- a/src/hotspot/share/memory/filemap.cpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/memory/filemap.cpp	Wed Sep 11 18:31:25 2019 -0700
@@ -192,9 +192,9 @@
   }
   _header = (FileMapHeader*)os::malloc(header_size, mtInternal);
   memset((void*)_header, 0, header_size);
-  _header->_header_size = header_size;
-  _header->_version = INVALID_CDS_ARCHIVE_VERSION;
-  _header->_has_platform_or_app_classes = true;
+  _header->set_header_size(header_size);
+  _header->set_version(INVALID_CDS_ARCHIVE_VERSION);
+  _header->set_has_platform_or_app_classes(true);
   _file_offset = 0;
   _file_open = false;
 }
@@ -210,7 +210,7 @@
 }
 
 void FileMapInfo::populate_header(size_t alignment) {
-  _header->populate(this, alignment);
+  header()->populate(this, alignment);
 }
 
 void FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
@@ -660,7 +660,7 @@
   char* runtime_boot_path = Arguments::get_sysclasspath();
   char* rp = skip_first_path_entry(runtime_boot_path);
   assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
-  int dp_len = _header->_app_class_paths_start_index - 1; // ignore the first path to the module image
+  int dp_len = header()->app_class_paths_start_index() - 1; // ignore the first path to the module image
   bool mismatch = false;
 
   bool relaxed_check = !header()->has_platform_or_app_classes();
@@ -723,7 +723,7 @@
     // run 1: -cp NE3:a.jar:NE4:b.jar  -> a.jar:b.jar -> matched
     // run 2: -cp x.jar:NE4:b.jar      -> x.jar:b.jar -> mismatched
 
-    int j = _header->_app_class_paths_start_index;
+    int j = header()->app_class_paths_start_index();
     mismatch = check_paths(j, shared_app_paths_len, rp_array);
     if (mismatch) {
       return fail("[APP classpath mismatch, actual: -Djava.class.path=", appcp);
@@ -752,7 +752,7 @@
   _validating_shared_path_table = true;
 
   // Load the shared path table info from the archive header
-  _shared_path_table = _header->_shared_path_table;
+  _shared_path_table = header()->shared_path_table();
   if (DynamicDumpSharedSpaces) {
     // Only support dynamic dumping with the usage of the default CDS archive
     // or a simple base archive.
@@ -762,30 +762,30 @@
     // When dynamic archiving is enabled, the _shared_path_table is overwritten
     // to include the application path and stored in the top layer archive.
     assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
-    if (_header->_app_class_paths_start_index > 1) {
+    if (header()->app_class_paths_start_index() > 1) {
       DynamicDumpSharedSpaces = false;
       warning(
         "Dynamic archiving is disabled because base layer archive has appended boot classpath");
     }
-    if (_header->_num_module_paths > 0) {
+    if (header()->num_module_paths() > 0) {
       DynamicDumpSharedSpaces = false;
       warning(
         "Dynamic archiving is disabled because base layer archive has module path");
     }
   }
 
-  log_paths("Expecting BOOT path=", 0, _header->_app_class_paths_start_index);
-  log_paths("Expecting -Djava.class.path=", _header->_app_class_paths_start_index, _header->_app_module_paths_start_index);
+  log_paths("Expecting BOOT path=", 0, header()->app_class_paths_start_index());
+  log_paths("Expecting -Djava.class.path=", header()->app_class_paths_start_index(), header()->app_module_paths_start_index());
 
-  int module_paths_start_index = _header->_app_module_paths_start_index;
+  int module_paths_start_index = header()->app_module_paths_start_index();
   int shared_app_paths_len = 0;
 
   // validate the path entries up to the _max_used_path_index
-  for (int i=0; i < _header->_max_used_path_index + 1; i++) {
+  for (int i=0; i < header()->max_used_path_index() + 1; i++) {
     if (i < module_paths_start_index) {
       if (shared_path(i)->validate()) {
         // Only count the app class paths not from the "Class-path" attribute of a jar manifest.
-        if (!shared_path(i)->from_class_path_attr() && i >= _header->_app_class_paths_start_index) {
+        if (!shared_path(i)->from_class_path_attr() && i >= header()->app_class_paths_start_index()) {
           shared_app_paths_len++;
         }
         log_info(class, path)("ok");
@@ -807,7 +807,7 @@
     }
   }
 
-  if (_header->_max_used_path_index == 0) {
+  if (header()->max_used_path_index() == 0) {
     // default archive only contains the module image in the bootclasspath
     assert(shared_path(0)->is_modules_image(), "first shared_path must be the modules image");
   } else {
@@ -841,14 +841,14 @@
   // app classes).
 
   assert(UseSharedSpaces, "runtime only");
-  for (int i = _header->_app_module_paths_start_index + _header->_num_module_paths;
+  for (int i = header()->app_module_paths_start_index() + header()->num_module_paths();
        i < get_number_of_shared_paths();
        i++) {
     SharedClassPathEntry* ent = shared_path(i);
     if (!ent->check_non_existent()) {
       warning("Archived non-system classes are disabled because the "
               "file %s exists", ent->name());
-      _header->_has_platform_or_app_classes = false;
+      header()->set_has_platform_or_app_classes(false);
     }
   }
 }
@@ -874,7 +874,7 @@
   }
   if (is_static) {
     FileMapHeader* static_header = (FileMapHeader*)header;
-    if (static_header->_magic != CDS_ARCHIVE_MAGIC) {
+    if (static_header->magic() != CDS_ARCHIVE_MAGIC) {
       os::free(header);
       os::close(fd);
       vm_exit_during_initialization("Not a base shared archive", archive_name);
@@ -882,7 +882,7 @@
     }
   } else {
     DynamicArchiveHeader* dynamic_header = (DynamicArchiveHeader*)header;
-    if (dynamic_header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC) {
+    if (dynamic_header->magic() != CDS_DYNAMIC_ARCHIVE_MAGIC) {
       os::free(header);
       os::close(fd);
       vm_exit_during_initialization("Not a top shared archive", archive_name);
@@ -912,18 +912,18 @@
     os::close(fd);
     return false;
   }
-  if (dynamic_header->_magic != CDS_DYNAMIC_ARCHIVE_MAGIC) {
+  if (dynamic_header->magic() != CDS_DYNAMIC_ARCHIVE_MAGIC) {
     // Not a dynamic header, no need to proceed further.
     *size = 0;
     os::free(dynamic_header);
     os::close(fd);
     return false;
   }
-  if (dynamic_header->_base_archive_is_default) {
+  if (dynamic_header->base_archive_is_default()) {
     *base_archive_name = Arguments::get_default_shared_archive_path();
   } else {
     // read the base archive name
-    size_t name_size = dynamic_header->_base_archive_name_size;
+    size_t name_size = dynamic_header->base_archive_name_size();
     if (name_size == 0) {
       os::free(dynamic_header);
       os::close(fd);
@@ -947,14 +947,14 @@
 }
 
 void FileMapInfo::restore_shared_path_table() {
-  _shared_path_table = _current_info->_header->_shared_path_table;
+  _shared_path_table = _current_info->header()->shared_path_table();
 }
 
 // Read the FileMapInfo information from the file.
 
 bool FileMapInfo::init_from_file(int fd, bool is_static) {
   size_t sz = is_static ? sizeof(FileMapHeader) : sizeof(DynamicArchiveHeader);
-  size_t n = os::read(fd, _header, (unsigned int)sz);
+  size_t n = os::read(fd, header(), (unsigned int)sz);
   if (n != sz) {
     fail_continue("Unable to read the file header.");
     return false;
@@ -966,66 +966,68 @@
   }
 
   unsigned int expected_magic = is_static ? CDS_ARCHIVE_MAGIC : CDS_DYNAMIC_ARCHIVE_MAGIC;
-  if (_header->_magic != expected_magic) {
+  if (header()->magic() != expected_magic) {
     log_info(cds)("_magic expected: 0x%08x", expected_magic);
-    log_info(cds)("         actual: 0x%08x", _header->_magic);
+    log_info(cds)("         actual: 0x%08x", header()->magic());
     FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
     return false;
   }
 
-  if (_header->_version != CURRENT_CDS_ARCHIVE_VERSION) {
+  if (header()->version() != CURRENT_CDS_ARCHIVE_VERSION) {
     log_info(cds)("_version expected: %d", CURRENT_CDS_ARCHIVE_VERSION);
-    log_info(cds)("           actual: %d", _header->_version);
+    log_info(cds)("           actual: %d", header()->version());
     fail_continue("The shared archive file has the wrong version.");
     return false;
   }
 
-  if (_header->_header_size != sz) {
+  if (header()->header_size() != sz) {
     log_info(cds)("_header_size expected: " SIZE_FORMAT, sz);
-    log_info(cds)("               actual: " SIZE_FORMAT, _header->_header_size);
+    log_info(cds)("               actual: " SIZE_FORMAT, header()->header_size());
     FileMapInfo::fail_continue("The shared archive file has an incorrect header size.");
     return false;
   }
 
-  if (_header->_jvm_ident[JVM_IDENT_MAX-1] != 0) {
+  const char* actual_ident = header()->jvm_ident();
+
+  if (actual_ident[JVM_IDENT_MAX-1] != 0) {
     FileMapInfo::fail_continue("JVM version identifier is corrupted.");
     return false;
   }
 
-  char header_version[JVM_IDENT_MAX];
-  get_header_version(header_version);
-  if (strncmp(_header->_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) {
-    log_info(cds)("_jvm_ident expected: %s", header_version);
-    log_info(cds)("             actual: %s", _header->_jvm_ident);
+  char expected_ident[JVM_IDENT_MAX];
+  get_header_version(expected_ident);
+  if (strncmp(actual_ident, expected_ident, JVM_IDENT_MAX-1) != 0) {
+    log_info(cds)("_jvm_ident expected: %s", expected_ident);
+    log_info(cds)("             actual: %s", actual_ident);
     FileMapInfo::fail_continue("The shared archive file was created by a different"
                   " version or build of HotSpot");
     return false;
   }
 
   if (VerifySharedSpaces) {
-    int expected_crc = _header->compute_crc();
-    if (expected_crc != _header->_crc) {
+    int expected_crc = header()->compute_crc();
+    if (expected_crc != header()->crc()) {
       log_info(cds)("_crc expected: %d", expected_crc);
-      log_info(cds)("       actual: %d", _header->_crc);
+      log_info(cds)("       actual: %d", header()->crc());
       FileMapInfo::fail_continue("Header checksum verification failed.");
       return false;
     }
   }
 
-  _file_offset = n + _header->_base_archive_name_size; // accounts for the size of _base_archive_name
+  _file_offset = n + header()->base_archive_name_size(); // accounts for the size of _base_archive_name
 
   if (is_static) {
     // just checking the last region is sufficient since the archive is written
     // in sequential order
     size_t len = lseek(fd, 0, SEEK_END);
-    CDSFileMapRegion* si = space_at(MetaspaceShared::last_valid_region);
+    FileMapRegion* si = space_at(MetaspaceShared::last_valid_region);
     // The last space might be empty
-    if (si->_file_offset > len || len - si->_file_offset < si->_used) {
+    if (si->file_offset() > len || len - si->file_offset() < si->used()) {
       fail_continue("The shared archive file has been truncated.");
       return false;
     }
 
-    SharedBaseAddress = _header->_shared_base_address;
+    SharedBaseAddress = header()->shared_base_address();
   }
 
   return true;
@@ -1095,20 +1097,41 @@
 
 void FileMapInfo::write_header() {
   char* base_archive_name = NULL;
-  if (_header->_magic == CDS_DYNAMIC_ARCHIVE_MAGIC) {
+  if (header()->magic() == CDS_DYNAMIC_ARCHIVE_MAGIC) {
     base_archive_name = (char*)Arguments::GetSharedArchivePath();
-    _header->_base_archive_name_size = (int)strlen(base_archive_name) + 1;
-    _header->_base_archive_is_default = FLAG_IS_DEFAULT(SharedArchiveFile);
+    header()->set_base_archive_name_size(strlen(base_archive_name) + 1);
+    header()->set_base_archive_is_default(FLAG_IS_DEFAULT(SharedArchiveFile));
   }
 
   assert(is_file_position_aligned(), "must be");
-  write_bytes(_header, _header->_header_size);
+  write_bytes(header(), header()->header_size());
   if (base_archive_name != NULL) {
-    write_bytes(base_archive_name, (size_t)_header->_base_archive_name_size);
+    write_bytes(base_archive_name, header()->base_archive_name_size());
   }
   align_file_position();
 }
 
+void FileMapRegion::init(bool is_heap_region, char* base, size_t size, bool read_only,
+                         bool allow_exec, int crc) {
+  _is_heap_region = is_heap_region;
+
+  if (is_heap_region) {
+    assert(!DynamicDumpSharedSpaces, "must be");
+    assert((base - (char*)CompressedKlassPointers::base()) % HeapWordSize == 0, "Sanity");
+    if (base != NULL) {
+      _addr._offset = (intx)CompressedOops::encode_not_null((oop)base);
+    } else {
+      _addr._offset = 0;
+    }
+  } else {
+    _addr._base = base;
+  }
+  _used = size;
+  _read_only = read_only;
+  _allow_exec = allow_exec;
+  _crc = crc;
+}
+
 // Dump region to file.
 // This is called twice for each region during archiving, once before
 // the archive file is open (_file_open is false) and once after.
@@ -1116,37 +1139,25 @@
                                bool read_only, bool allow_exec) {
   assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Dump time only");
 
-  CDSFileMapRegion* si = space_at(region);
+  FileMapRegion* si = space_at(region);
   char* target_base = base;
   if (DynamicDumpSharedSpaces) {
+    assert(!HeapShared::is_heap_region(region), "dynamic archive doesn't support heap regions");
     target_base = DynamicArchive::buffer_to_target(base);
   }
 
   if (_file_open) {
-    guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
+    guarantee(si->file_offset() == _file_offset, "file offset mismatch.");
     log_info(cds)("Shared file region %d: " SIZE_FORMAT_HEX_W(08)
                   " bytes, addr " INTPTR_FORMAT " file offset " SIZE_FORMAT_HEX_W(08),
                   region, size, p2i(target_base), _file_offset);
   } else {
-    si->_file_offset = _file_offset;
+    si->set_file_offset(_file_offset);
   }
 
-  if (HeapShared::is_heap_region(region)) {
-    assert((target_base - (char*)CompressedKlassPointers::base()) % HeapWordSize == 0, "Sanity");
-    if (target_base != NULL) {
-      si->_addr._offset = (intx)CompressedOops::encode_not_null((oop)target_base);
-    } else {
-      si->_addr._offset = 0;
-    }
-  } else {
-    si->_addr._base = target_base;
-  }
-  si->_used = size;
-  si->_read_only = read_only;
-  si->_allow_exec = allow_exec;
+  int crc = ClassLoader::crc32(0, base, (jint)size);
+  si->init(HeapShared::is_heap_region(region), target_base, size, read_only, allow_exec, crc);
 
-  // Use the current 'base' when computing the CRC value and writing out data
-  si->_crc = ClassLoader::crc32(0, base, (jint)size);
   if (base != NULL) {
     write_bytes_aligned(base, size);
   }
@@ -1216,8 +1227,8 @@
     }
     write_region(i, start, size, false, false);
     if (size > 0) {
-      space_at(i)->_oopmap = oopmaps->at(arr_idx)._oopmap;
-      space_at(i)->_oopmap_size_in_bits = oopmaps->at(arr_idx)._oopmap_size_in_bits;
+      space_at(i)->init_oopmap(oopmaps->at(arr_idx)._oopmap,
+                               oopmaps->at(arr_idx)._oopmap_size_in_bits);
     }
   }
   return total_size;
@@ -1290,20 +1301,20 @@
 // Remap the shared readonly space to shared readwrite, private.
 bool FileMapInfo::remap_shared_readonly_as_readwrite() {
   int idx = MetaspaceShared::ro;
-  CDSFileMapRegion* si = space_at(idx);
-  if (!si->_read_only) {
+  FileMapRegion* si = space_at(idx);
+  if (!si->read_only()) {
     // the space is already readwrite so we are done
     return true;
   }
-  size_t used = si->_used;
+  size_t used = si->used();
   size_t size = align_up(used, os::vm_allocation_granularity());
   if (!open_for_read()) {
     return false;
   }
   char *addr = region_addr(idx);
-  char *base = os::remap_memory(_fd, _full_path, si->_file_offset,
+  char *base = os::remap_memory(_fd, _full_path, si->file_offset(),
                                 addr, size, false /* !read_only */,
-                                si->_allow_exec);
+                                si->allow_exec());
   close();
   // These have to be errors because the shared region is now unmapped.
   if (base == NULL) {
@@ -1314,7 +1325,7 @@
     log_error(cds)("Unable to remap shared readonly space (errno=%d).", errno);
     vm_exit(1);
   }
-  si->_read_only = false;
+  si->set_read_only(false);
   return true;
 }
 
@@ -1367,8 +1378,8 @@
 
 char* FileMapInfo::map_region(int i, char** top_ret) {
   assert(!HeapShared::is_heap_region(i), "sanity");
-  CDSFileMapRegion* si = space_at(i);
-  size_t used = si->_used;
+  FileMapRegion* si = space_at(i);
+  size_t used = si->used();
   size_t alignment = os::vm_allocation_granularity();
   size_t size = align_up(used, alignment);
   char *requested_addr = region_addr(i);
@@ -1376,19 +1387,19 @@
 #ifdef _WINDOWS
   // Windows cannot remap read-only shared memory to read-write when required for
   // RedefineClasses, which is also used by JFR.  Always map windows regions as RW.
-  si->_read_only = false;
+  si->set_read_only(false);
 #else
   // If a tool agent is in use (debugging enabled), or JFR, we must map the address space RW
   if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space() ||
       Arguments::has_jfr_option()) {
-    si->_read_only = false;
+    si->set_read_only(false);
   }
 #endif // _WINDOWS
 
   // map the contents of the CDS archive in this memory
-  char *base = os::map_memory(_fd, _full_path, si->_file_offset,
-                              requested_addr, size, si->_read_only,
-                              si->_allow_exec);
+  char *base = os::map_memory(_fd, _full_path, si->file_offset(),
+                              requested_addr, size, si->read_only(),
+                              si->allow_exec());
   if (base == NULL || base != requested_addr) {
     fail_continue("Unable to map %s shared space at required address.", shared_region_name[i]);
     _memory_mapping_failed = true;
@@ -1420,11 +1431,11 @@
   return count;
 }
 
-address FileMapInfo::decode_start_address(CDSFileMapRegion* spc, bool with_current_oop_encoding_mode) {
+address FileMapInfo::decode_start_address(FileMapRegion* spc, bool with_current_oop_encoding_mode) {
   if (with_current_oop_encoding_mode) {
-    return (address)CompressedOops::decode_not_null(offset_of_space(spc));
+    return (address)CompressedOops::decode_not_null(spc->offset());
   } else {
-    return (address)HeapShared::decode_from_archive(offset_of_space(spc));
+    return (address)HeapShared::decode_from_archive(spc->offset());
   }
 }
 
@@ -1435,7 +1446,7 @@
 
 #if INCLUDE_CDS_JAVA_HEAP
 bool FileMapInfo::has_heap_regions() {
-  return (_header->_space[MetaspaceShared::first_closed_archive_heap_region]._used > 0);
+  return (space_at(MetaspaceShared::first_closed_archive_heap_region)->used() > 0);
 }
 
 // Returns the address range of the archived heap regions computed using the
@@ -1449,8 +1460,8 @@
   for (int i = MetaspaceShared::first_closed_archive_heap_region;
            i <= MetaspaceShared::last_valid_region;
            i++) {
-    CDSFileMapRegion* si = space_at(i);
-    size_t size = si->_used;
+    FileMapRegion* si = space_at(i);
+    size_t size = si->used();
     if (size > 0) {
       address s = start_address_as_decoded_with_current_oop_encoding_mode(si);
       address e = s + size;
@@ -1546,7 +1557,7 @@
     // At run time, they may not be inside the heap, so we move them so
     // that they are now near the top of the runtime time. This can be done by
     // the simple math of adding the delta as shown above.
-    address dumptime_heap_end = (address)_header->_heap_end;
+    address dumptime_heap_end = header()->heap_end();
     address runtime_heap_end = (address)CompressedOops::end();
     delta = runtime_heap_end - dumptime_heap_end;
   }
@@ -1554,7 +1565,7 @@
   log_info(cds)("CDS heap data relocation delta = " INTX_FORMAT " bytes", delta);
   HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift());
 
-  CDSFileMapRegion* si = space_at(MetaspaceShared::first_closed_archive_heap_region);
+  FileMapRegion* si = space_at(MetaspaceShared::first_closed_archive_heap_region);
   address relocated_closed_heap_region_bottom = start_address_as_decoded_from_archive(si);
   if (!is_aligned(relocated_closed_heap_region_bottom, HeapRegion::GrainBytes)) {
     // Align the bottom of the closed archive heap regions at G1 region boundary.
@@ -1609,13 +1620,13 @@
 bool FileMapInfo::map_heap_data(MemRegion **heap_mem, int first,
                                 int max, int* num, bool is_open_archive) {
   MemRegion * regions = new MemRegion[max];
-  CDSFileMapRegion* si;
+  FileMapRegion* si;
   int region_num = 0;
 
   for (int i = first;
            i < first + max; i++) {
     si = space_at(i);
-    size_t size = si->_used;
+    size_t size = si->used();
     if (size > 0) {
       HeapWord* start = (HeapWord*)start_address_as_decoded_from_archive(si);
       regions[region_num] = MemRegion(start, size / HeapWordSize);
@@ -1648,9 +1659,9 @@
   for (int i = 0; i < region_num; i++) {
     si = space_at(first + i);
     char* addr = (char*)regions[i].start();
-    char* base = os::map_memory(_fd, _full_path, si->_file_offset,
-                                addr, regions[i].byte_size(), si->_read_only,
-                                si->_allow_exec);
+    char* base = os::map_memory(_fd, _full_path, si->file_offset(),
+                                addr, regions[i].byte_size(), si->read_only(),
+                                si->allow_exec());
     if (base == NULL || base != addr) {
       // dealloc the regions from java heap
       dealloc_archive_heap_regions(regions, region_num, is_open_archive);
@@ -1660,7 +1671,7 @@
       return false;
     }
 
-    if (VerifySharedSpaces && !region_crc_check(addr, regions[i].byte_size(), si->_crc)) {
+    if (VerifySharedSpaces && !region_crc_check(addr, regions[i].byte_size(), si->crc())) {
       // dealloc the regions from java heap
       dealloc_archive_heap_regions(regions, region_num, is_open_archive);
       log_info(cds)("UseSharedSpaces: mapped heap regions are corrupt");
@@ -1691,9 +1702,9 @@
 void FileMapInfo::patch_archived_heap_embedded_pointers(MemRegion* ranges, int num_ranges,
                                                         int first_region_idx) {
   for (int i=0; i<num_ranges; i++) {
-    CDSFileMapRegion* si = space_at(i + first_region_idx);
-    HeapShared::patch_archived_heap_embedded_pointers(ranges[i], (address)si->_oopmap,
-                                                      si->_oopmap_size_in_bits);
+    FileMapRegion* si = space_at(i + first_region_idx);
+    HeapShared::patch_archived_heap_embedded_pointers(ranges[i], (address)si->oopmap(),
+                                                      si->oopmap_size_in_bits());
   }
 }
 
@@ -1737,14 +1748,13 @@
 
 bool FileMapInfo::verify_region_checksum(int i) {
   assert(VerifySharedSpaces, "sanity");
-
-  size_t sz = space_at(i)->_used;
+  size_t sz = space_at(i)->used();
 
   if (sz == 0) {
     return true; // no data
+  } else {
+    return region_crc_check(region_addr(i), sz, space_at(i)->crc());
   }
-
-  return region_crc_check(region_addr(i), sz, space_at(i)->_crc);
 }
 
 void FileMapInfo::unmap_regions(int regions[], char* saved_base[], size_t len) {
@@ -1759,8 +1769,8 @@
 
 void FileMapInfo::unmap_region(int i) {
   assert(!HeapShared::is_heap_region(i), "sanity");
-  CDSFileMapRegion* si = space_at(i);
-  size_t used = si->_used;
+  FileMapRegion* si = space_at(i);
+  size_t used = si->used();
   size_t size = align_up(used, os::vm_allocation_granularity());
 
   if (used == 0) {
@@ -1827,13 +1837,13 @@
 }
 
 char* FileMapInfo::region_addr(int idx) {
-  CDSFileMapRegion* si = space_at(idx);
+  FileMapRegion* si = space_at(idx);
   if (HeapShared::is_heap_region(idx)) {
     assert(DumpSharedSpaces, "The following doesn't work at runtime");
-    return si->_used > 0 ?
+    return si->used() > 0 ?
           (char*)start_address_as_decoded_with_current_oop_encoding_mode(si) : NULL;
   } else {
-    return si->_addr._base;
+    return si->base();
   }
 }
 
@@ -1902,7 +1912,7 @@
 }
 
 bool FileMapInfo::validate_header(bool is_static) {
-  return _header->validate();
+  return header()->validate();
 }
 
 // Check if a given address is within one of the shared regions
@@ -1912,7 +1922,7 @@
          idx == MetaspaceShared::mc ||
          idx == MetaspaceShared::md, "invalid region index");
   char* base = region_addr(idx);
-  if (p >= base && p < base + space_at(idx)->_used) {
+  if (p >= base && p < base + space_at(idx)->used()) {
     return true;
   }
   return false;
@@ -1930,7 +1940,7 @@
         char *addr = map_info->region_addr(i);
         if (addr != NULL) {
           map_info->unmap_region(i);
-          map_info->space_at(i)->_addr._base = NULL;
+          map_info->space_at(i)->mark_invalid();
         }
       }
     }
--- a/src/hotspot/share/memory/filemap.hpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/memory/filemap.hpp	Wed Sep 11 18:31:25 2019 -0700
@@ -55,7 +55,6 @@
 
   void set_name(const char* name, TRAPS);
 
-protected:
   u1     _type;
   bool   _from_class_path_attr;
   time_t _timestamp;          // jar timestamp,  0 if is directory, modules image or other
@@ -122,24 +121,70 @@
   }
   Array<u8>* table() {return _table;}
   void set_table(Array<u8>* table) {_table = table;}
-
 };
 
-struct FileMapHeader : public CDSFileMapHeaderBase {
+
+class FileMapRegion: private CDSFileMapRegion {
+  void assert_is_heap_region() const {
+    assert(_is_heap_region, "must be heap region");
+  }
+  void assert_is_not_heap_region() const {
+    assert(!_is_heap_region, "must not be heap region");
+  }
+
+public:
+  static FileMapRegion* cast(CDSFileMapRegion* p) {
+    return (FileMapRegion*)p;
+  }
+
+  // Accessors
+  int crc()                      const { return _crc; }
+  size_t file_offset()           const { return _file_offset; }
+  char*  base()                  const { assert_is_not_heap_region(); return _addr._base;  }
+  narrowOop offset()             const { assert_is_heap_region();     return (narrowOop)(_addr._offset); }
+  size_t used()                  const { return _used; }
+  bool read_only()               const { return _read_only != 0; }
+  bool allow_exec()              const { return _allow_exec != 0; }
+  void* oopmap()                 const { return _oopmap; }
+  size_t oopmap_size_in_bits()   const { return _oopmap_size_in_bits; }
+
+  void set_file_offset(size_t s) { _file_offset = s; }
+  void set_read_only(bool v)     { _read_only = v; }
+  void mark_invalid()            { _addr._base = NULL; }
+
+  void init(bool is_heap_region, char* base, size_t size, bool read_only,
+            bool allow_exec, int crc);
+
+  void init_oopmap(void* map, size_t size_in_bits) {
+    _oopmap = map;
+    _oopmap_size_in_bits = size_in_bits;
+  }
+};
+
+class FileMapHeader: private CDSFileMapHeaderBase {
+  friend class CDSOffsets;
+  friend class VMStructs;
+
   size_t _header_size;
+
+  // The following fields record the states of the VM during dump time.
+  // They are compared with the runtime states to see if the archive
+  // can be used.
   size_t _alignment;                // how shared archive should be aligned
   int    _obj_alignment;            // value of ObjectAlignmentInBytes
   address _narrow_oop_base;         // compressed oop encoding base
   int    _narrow_oop_shift;         // compressed oop encoding shift
-  bool    _compact_strings;         // value of CompactStrings
+  bool   _compact_strings;          // value of CompactStrings
   uintx  _max_heap_size;            // java max heap size during dumping
   CompressedOops::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;
   char*   _read_only_tables_start;
-  address _cds_i2i_entry_code_buffers;
-  size_t  _cds_i2i_entry_code_buffers_size;
+  address _i2i_entry_code_buffers;
+  size_t  _i2i_entry_code_buffers_size;
   size_t  _core_spaces_size;        // number of bytes allocated by the core spaces
                                     // (mc, md, ro, rw and od).
   address _heap_end;                // heap end at dump time.
@@ -148,10 +193,10 @@
   // The following fields are all sanity checks for whether this archive
   // will function correctly with this JVM and the bootclasspath it's
   // invoked with.
-  char  _jvm_ident[JVM_IDENT_MAX];      // identifier for jvm
+  char  _jvm_ident[JVM_IDENT_MAX];  // identifier string of the jvm that created this dump
 
   // size of the base archive name including NULL terminator
-  int _base_archive_name_size;
+  size_t _base_archive_name_size;
 
   // The following is a table of all the boot/app/module path entries that were used
   // during dumping. At run time, we validate these entries according to their
@@ -171,36 +216,99 @@
   size_t _shared_base_address;          // SharedBaseAddress used at dump time
   bool   _allow_archiving_with_java_agent; // setting of the AllowArchivingWithJavaAgent option
 
-  void set_has_platform_or_app_classes(bool v) {
-    _has_platform_or_app_classes = v;
+public:
+  // Accessors -- fields declared in CDSFileMapHeaderBase
+  unsigned int magic() const {return _magic;}
+  int crc()                               const { return _crc; }
+  int version()                           const { return _version; }
+
+  void set_crc(int crc_value)                   { _crc = crc_value; }
+  void set_version(int v)                       { _version = v; }
+
+  // Accessors -- fields declared in FileMapHeader
+
+  size_t header_size()                     const { return _header_size; }
+  size_t alignment()                       const { return _alignment; }
+  int obj_alignment()                      const { return _obj_alignment; }
+  address narrow_oop_base()                const { return _narrow_oop_base; }
+  int narrow_oop_shift()                   const { return _narrow_oop_shift; }
+  bool compact_strings()                   const { return _compact_strings; }
+  uintx max_heap_size()                    const { return _max_heap_size; }
+  CompressedOops::Mode narrow_oop_mode()   const { return _narrow_oop_mode; }
+  int narrow_klass_shift()                 const { return _narrow_klass_shift; }
+  address narrow_klass_base()              const { return _narrow_klass_base; }
+  char* misc_data_patching_start()         const { return _misc_data_patching_start; }
+  char* read_only_tables_start()           const { return _read_only_tables_start; }
+  address i2i_entry_code_buffers()         const { return _i2i_entry_code_buffers; }
+  size_t i2i_entry_code_buffers_size()     const { return _i2i_entry_code_buffers_size; }
+  size_t core_spaces_size()                const { return _core_spaces_size; }
+  address heap_end()                       const { return _heap_end; }
+  bool base_archive_is_default()           const { return _base_archive_is_default; }
+  const char* jvm_ident()                  const { return _jvm_ident; }
+  size_t base_archive_name_size()          const { return _base_archive_name_size; }
+  size_t shared_base_address()             const { return _shared_base_address; }
+  bool has_platform_or_app_classes()       const { return _has_platform_or_app_classes; }
+  SharedPathTable shared_path_table()      const { return _shared_path_table; }
+
+  // FIXME: These should really return int
+  jshort max_used_path_index()             const { return _max_used_path_index; }
+  jshort app_module_paths_start_index()    const { return _app_module_paths_start_index; }
+  jshort app_class_paths_start_index()     const { return _app_class_paths_start_index; }
+  jshort num_module_paths()                const { return _num_module_paths; }
+
+  void set_core_spaces_size(size_t s)            { _core_spaces_size = s; }
+  void set_has_platform_or_app_classes(bool v)   { _has_platform_or_app_classes = v; }
+  void set_misc_data_patching_start(char* p)     { _misc_data_patching_start = p; }
+  void set_read_only_tables_start(char* p)       { _read_only_tables_start   = p; }
+  void set_base_archive_name_size(size_t s)      { _base_archive_name_size = s; }
+  void set_base_archive_is_default(bool b)       { _base_archive_is_default = b; }
+  void set_header_size(size_t s)                 { _header_size = s; }
+
+  void set_i2i_entry_code_buffers(address p, size_t s) {
+    _i2i_entry_code_buffers = p;
+    _i2i_entry_code_buffers_size = s;
   }
-  bool has_platform_or_app_classes() { return _has_platform_or_app_classes; }
-  jshort max_used_path_index()       { return _max_used_path_index; }
-  jshort app_module_paths_start_index() { return _app_module_paths_start_index; }
+
+  void relocate_shared_path_table(Array<u8>* t) {
+    assert(DynamicDumpSharedSpaces, "only");
+    _shared_path_table.set_table(t);
+  }
+
+  void shared_path_table_metaspace_pointers_do(MetaspaceClosure* it) {
+    assert(DynamicDumpSharedSpaces, "only");
+    _shared_path_table.metaspace_pointers_do(it);
+  }
 
   bool validate();
   int compute_crc();
 
-  CDSFileMapRegion* space_at(int i) {
-    assert(i >= 0 && i < NUM_CDS_REGIONS, "invalid region");
-    return &_space[i];
+  FileMapRegion* space_at(int i) {
+    assert(is_valid_region(i), "invalid region");
+    return FileMapRegion::cast(&_space[i]);
   }
-public:
+
   void populate(FileMapInfo* info, size_t alignment);
+
+  static bool is_valid_region(int region) {
+    return (0 <= region && region < NUM_CDS_REGIONS);
+  }
 };
 
 class FileMapInfo : public CHeapObj<mtInternal> {
 private:
   friend class ManifestStream;
   friend class VMStructs;
-  friend struct FileMapHeader;
+  friend class CDSOffsets;
+  friend class FileMapHeader;
 
-  bool    _is_static;
-  bool    _file_open;
-  int     _fd;
-  size_t  _file_offset;
+  bool           _is_static;
+  bool           _file_open;
+  int            _fd;
+  size_t         _file_offset;
+  const char*    _full_path;
+  const char*    _base_archive_name;
+  FileMapHeader* _header;
 
-private:
   // TODO: Probably change the following to be non-static
   static SharedPathTable       _shared_path_table;
   static bool                  _validating_shared_path_table;
@@ -209,76 +317,75 @@
   // mapped.  This structure gets written to a file.  It is not a class, so
   // that the compilers don't add any compiler-private data to it.
 
-public:
-  struct FileMapHeaderBase : public CHeapObj<mtClass> {
-    // Need to put something here. Otherwise, in product build, because CHeapObj has no virtual
-    // methods, we would get sizeof(FileMapHeaderBase) == 1 with gcc.
-    intx _dummy;
-  };
-
-
-  FileMapHeader * _header;
-
-  const char* _full_path;
-  char* _base_archive_name;
-
   static FileMapInfo* _current_info;
   static FileMapInfo* _dynamic_archive_info;
   static bool _heap_pointers_need_patching;
   static bool _memory_mapping_failed;
   static GrowableArray<const char*>* _non_existent_class_paths;
 
+  FileMapHeader *header() const       { return _header; }
+
+public:
   static bool get_base_archive_name_from_header(const char* archive_name,
                                                 int* size, char** base_archive_name);
   static bool check_archive(const char* archive_name, bool is_static);
   void restore_shared_path_table();
-  bool  init_from_file(int fd, bool is_static);
+  bool init_from_file(int fd, bool is_static);
   static void metaspace_pointers_do(MetaspaceClosure* it);
 
   void log_paths(const char* msg, int start_idx, int end_idx);
 
-public:
   FileMapInfo(bool is_static);
   ~FileMapInfo();
 
-  int    compute_header_crc()         { return _header->compute_crc(); }
-  void   set_header_crc(int crc)      { _header->_crc = crc; }
-  int    space_crc(int i)             { return space_at(i)->_crc; }
+  // Accessors
+  int    compute_header_crc()  const { return header()->compute_crc(); }
+  void   set_header_crc(int crc)     { header()->set_crc(crc); }
+  int    space_crc(int i)      const { return space_at(i)->crc(); }
   void   populate_header(size_t alignment);
   bool   validate_header(bool is_static);
   void   invalidate();
-  int    crc()                        { return _header->_crc; }
-  int    version()                    { return _header->_version; }
-  size_t alignment()                  { return _header->_alignment; }
-  CompressedOops::Mode narrow_oop_mode() { return _header->_narrow_oop_mode; }
-  address narrow_oop_base()    const  { return _header->_narrow_oop_base; }
-  int     narrow_oop_shift()   const  { return _header->_narrow_oop_shift; }
-  uintx   max_heap_size()      const  { return _header->_max_heap_size; }
-  address narrow_klass_base()  const  { return _header->_narrow_klass_base; }
-  int     narrow_klass_shift() const  { return _header->_narrow_klass_shift; }
-  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; }
-  char* read_only_tables_start()              { return _header->_read_only_tables_start; }
-  void set_read_only_tables_start(char* p)    { _header->_read_only_tables_start = p; }
+  int    crc()                 const { return header()->crc(); }
+  int    version()             const { return header()->version(); }
+  size_t alignment()           const { return header()->alignment(); }
+  address narrow_oop_base()    const { return header()->narrow_oop_base(); }
+  int     narrow_oop_shift()   const { return header()->narrow_oop_shift(); }
+  uintx   max_heap_size()      const { return header()->max_heap_size(); }
+  address narrow_klass_base()  const { return header()->narrow_klass_base(); }
+  int     narrow_klass_shift() const { return header()->narrow_klass_shift(); }
+
+  CompressedOops::Mode narrow_oop_mode()      const { return header()->narrow_oop_mode(); }
+  jshort app_module_paths_start_index()       const { return header()->app_module_paths_start_index(); }
+  jshort app_class_paths_start_index()        const { return header()->app_class_paths_start_index(); }
+
+  char* misc_data_patching_start()            const { return header()->misc_data_patching_start(); }
+  void  set_misc_data_patching_start(char* p) const { header()->set_misc_data_patching_start(p); }
+  char* read_only_tables_start()              const { return header()->read_only_tables_start(); }
+  void  set_read_only_tables_start(char* p)   const { header()->set_read_only_tables_start(p); }
 
   bool  is_file_position_aligned() const;
   void  align_file_position();
 
-  address cds_i2i_entry_code_buffers() {
-    return _header->_cds_i2i_entry_code_buffers;
+  address i2i_entry_code_buffers()            const { return header()->i2i_entry_code_buffers();  }
+  size_t i2i_entry_code_buffers_size()        const { return header()->i2i_entry_code_buffers_size(); }
+  void set_i2i_entry_code_buffers(address addr, size_t s) const {
+    header()->set_i2i_entry_code_buffers(addr, s);
   }
-  void set_cds_i2i_entry_code_buffers(address addr) {
-    _header->_cds_i2i_entry_code_buffers = addr;
+
+  void set_core_spaces_size(size_t s)         const { header()->set_core_spaces_size(s); }
+  size_t core_spaces_size()                   const { return header()->core_spaces_size(); }
+
+  class DynamicArchiveHeader* dynamic_header() const {
+    assert(!_is_static, "must be");
+    return (DynamicArchiveHeader*)header();
   }
-  size_t cds_i2i_entry_code_buffers_size() {
-    return _header->_cds_i2i_entry_code_buffers_size;
+
+  void set_has_platform_or_app_classes(bool v) {
+    header()->set_has_platform_or_app_classes(v);
   }
-  void set_cds_i2i_entry_code_buffers_size(size_t s) {
-    _header->_cds_i2i_entry_code_buffers_size = s;
+  bool has_platform_or_app_classes() const {
+    return header()->has_platform_or_app_classes();
   }
-  void set_core_spaces_size(size_t s)    {  _header->_core_spaces_size = s; }
-  size_t core_spaces_size()              { return _header->_core_spaces_size; }
 
   static FileMapInfo* current_info() {
     CDS_ONLY(return _current_info;)
@@ -385,25 +492,21 @@
   bool  region_crc_check(char* buf, size_t size, int expected_crc) NOT_CDS_RETURN_(false);
   void  dealloc_archive_heap_regions(MemRegion* regions, int num, bool is_open) NOT_CDS_JAVA_HEAP_RETURN;
 
-  CDSFileMapRegion* space_at(int i) {
-    return _header->space_at(i);
-  }
-
-  narrowOop offset_of_space(CDSFileMapRegion* spc) {
-    return (narrowOop)(spc->_addr._offset);
+  FileMapRegion* space_at(int i) const {
+    return header()->space_at(i);
   }
 
   // The starting address of spc, as calculated with CompressedOop::decode_non_null()
-  address start_address_as_decoded_with_current_oop_encoding_mode(CDSFileMapRegion* spc) {
+  address start_address_as_decoded_with_current_oop_encoding_mode(FileMapRegion* spc) {
     return decode_start_address(spc, true);
   }
 
   // The starting address of spc, as calculated with HeapShared::decode_from_archive()
-  address start_address_as_decoded_from_archive(CDSFileMapRegion* spc) {
+  address start_address_as_decoded_from_archive(FileMapRegion* spc) {
     return decode_start_address(spc, false);
   }
 
-  address decode_start_address(CDSFileMapRegion* spc, bool with_current_oop_encoding_mode);
+  address decode_start_address(FileMapRegion* spc, bool with_current_oop_encoding_mode);
 
 #if INCLUDE_JVMTI
   static ClassPathEntry** _classpath_entries_for_jvmti;
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Wed Sep 11 18:31:25 2019 -0700
@@ -80,8 +80,8 @@
 bool MetaspaceShared::_has_error_classes;
 bool MetaspaceShared::_archive_loading_failed = false;
 bool MetaspaceShared::_remapped_readwrite = false;
-address MetaspaceShared::_cds_i2i_entry_code_buffers = NULL;
-size_t MetaspaceShared::_cds_i2i_entry_code_buffers_size = 0;
+address MetaspaceShared::_i2i_entry_code_buffers = NULL;
+size_t MetaspaceShared::_i2i_entry_code_buffers_size = 0;
 size_t MetaspaceShared::_core_spaces_size = 0;
 void* MetaspaceShared::_shared_metaspace_static_top = NULL;
 
@@ -356,14 +356,14 @@
     if (size > 0) {
       SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
       if (!DynamicDumpSharedSpaces) {
-        FileMapHeader* header;
+        FileMapInfo* info;
         if (FileMapInfo::dynamic_info() == NULL) {
-          header = FileMapInfo::current_info()->header();
+          info = FileMapInfo::current_info();
         } else {
-          header = FileMapInfo::dynamic_info()->header();
+          info = FileMapInfo::dynamic_info();
         }
-        ClassLoaderExt::init_paths_start_index(header->_app_class_paths_start_index);
-        ClassLoaderExt::init_app_module_paths_start_index(header->_app_module_paths_start_index);
+        ClassLoaderExt::init_paths_start_index(info->app_class_paths_start_index());
+        ClassLoaderExt::init_app_module_paths_start_index(info->app_module_paths_start_index());
       }
     }
   }
@@ -492,20 +492,20 @@
   soc->do_tag(666);
 }
 
-address MetaspaceShared::cds_i2i_entry_code_buffers(size_t total_size) {
+address MetaspaceShared::i2i_entry_code_buffers(size_t total_size) {
   if (DumpSharedSpaces) {
-    if (_cds_i2i_entry_code_buffers == NULL) {
-      _cds_i2i_entry_code_buffers = (address)misc_code_space_alloc(total_size);
-      _cds_i2i_entry_code_buffers_size = total_size;
+    if (_i2i_entry_code_buffers == NULL) {
+      _i2i_entry_code_buffers = (address)misc_code_space_alloc(total_size);
+      _i2i_entry_code_buffers_size = total_size;
     }
   } else if (UseSharedSpaces) {
-    assert(_cds_i2i_entry_code_buffers != NULL, "must already been initialized");
+    assert(_i2i_entry_code_buffers != NULL, "must already been initialized");
   } else {
     return NULL;
   }
 
-  assert(_cds_i2i_entry_code_buffers_size == total_size, "must not change");
-  return _cds_i2i_entry_code_buffers;
+  assert(_i2i_entry_code_buffers_size == total_size, "must not change");
+  return _i2i_entry_code_buffers;
 }
 
 uintx MetaspaceShared::object_delta_uintx(void* obj) {
@@ -1545,8 +1545,8 @@
   mapinfo->populate_header(os::vm_allocation_granularity());
   mapinfo->set_read_only_tables_start(read_only_tables_start);
   mapinfo->set_misc_data_patching_start(vtbl_list);
-  mapinfo->set_cds_i2i_entry_code_buffers(MetaspaceShared::cds_i2i_entry_code_buffers());
-  mapinfo->set_cds_i2i_entry_code_buffers_size(MetaspaceShared::cds_i2i_entry_code_buffers_size());
+  mapinfo->set_i2i_entry_code_buffers(MetaspaceShared::i2i_entry_code_buffers(),
+                                          MetaspaceShared::i2i_entry_code_buffers_size());
   mapinfo->set_core_spaces_size(core_spaces_size);
 
   for (int pass=1; pass<=2; pass++) {
@@ -2043,8 +2043,8 @@
 
 void MetaspaceShared::initialize_shared_spaces() {
   FileMapInfo *mapinfo = FileMapInfo::current_info();
-  _cds_i2i_entry_code_buffers = mapinfo->cds_i2i_entry_code_buffers();
-  _cds_i2i_entry_code_buffers_size = mapinfo->cds_i2i_entry_code_buffers_size();
+  _i2i_entry_code_buffers = mapinfo->i2i_entry_code_buffers();
+  _i2i_entry_code_buffers_size = mapinfo->i2i_entry_code_buffers_size();
   // _core_spaces_size is loaded from the shared archive immediatelly after mapping
   assert(_core_spaces_size == mapinfo->core_spaces_size(), "sanity");
   char* buffer = mapinfo->misc_data_patching_start();
--- a/src/hotspot/share/memory/metaspaceShared.hpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/memory/metaspaceShared.hpp	Wed Sep 11 18:31:25 2019 -0700
@@ -183,8 +183,8 @@
   static bool _has_error_classes;
   static bool _archive_loading_failed;
   static bool _remapped_readwrite;
-  static address _cds_i2i_entry_code_buffers;
-  static size_t  _cds_i2i_entry_code_buffers_size;
+  static address _i2i_entry_code_buffers;
+  static size_t  _i2i_entry_code_buffers_size;
   static size_t  _core_spaces_size;
   static void* _shared_metaspace_static_top;
  public:
@@ -332,13 +332,13 @@
     return align_up(byte_size, BytesPerWord);
   }
 
-  static address cds_i2i_entry_code_buffers(size_t total_size);
+  static address i2i_entry_code_buffers(size_t total_size);
 
-  static address cds_i2i_entry_code_buffers() {
-    return _cds_i2i_entry_code_buffers;
+  static address i2i_entry_code_buffers() {
+    return _i2i_entry_code_buffers;
   }
-  static size_t cds_i2i_entry_code_buffers_size() {
-    return _cds_i2i_entry_code_buffers_size;
+  static size_t i2i_entry_code_buffers_size() {
+    return _i2i_entry_code_buffers_size;
   }
   static void relocate_klass_ptr(oop o);
 
--- a/src/hotspot/share/prims/cdsoffsets.cpp	Wed Sep 11 22:09:05 2019 -0400
+++ b/src/hotspot/share/prims/cdsoffsets.cpp	Wed Sep 11 18:31:25 2019 -0700
@@ -54,7 +54,7 @@
     ADD_NEXT(_all, "CDSFileMapRegion::_crc", offset_of(CDSFileMapRegion, _crc));            \
     ADD_NEXT(_all, "CDSFileMapRegion::_used", offset_of(CDSFileMapRegion, _used));          \
     ADD_NEXT(_all, "file_header_size", sizeof(FileMapHeader));                              \
-    ADD_NEXT(_all, "DynamicArchiveHeader::_base_archive_crc", offset_of(DynamicArchiveHeader, _base_archive_crc)); \
+    ADD_NEXT(_all, "DynamicArchiveHeader::_base_region_crc", offset_of(DynamicArchiveHeader, _base_region_crc)); \
     ADD_NEXT(_all, "CDSFileMapRegion_size", sizeof(CDSFileMapRegion));
 
 int CDSOffsets::find_offset(const char* name) {
--- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java	Wed Sep 11 22:09:05 2019 -0400
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/ArchiveConsistency.java	Wed Sep 11 18:31:25 2019 -0700
@@ -114,7 +114,7 @@
             bbuf.put((byte)0);
         }
 
-        int baseArchiveCRCOffset = wb.getOffsetForName("DynamicArchiveHeader::_base_archive_crc");
+        int baseArchiveCRCOffset = wb.getOffsetForName("DynamicArchiveHeader::_base_region_crc");
         int crc = 0;
         System.out.printf("%-12s%-12s\n", "Space name", "CRC");
         for (int i = 0; i < 4; i++) {