changeset 51477:e77d7687c831

8209657: Refactor filemap.hpp to simplify integration with Serviceability Agent Summary: Added src/hotspot/share/include/cds.h Reviewed-by: ccheung, sspitsyn, jgeorge
author iklam
date Fri, 17 Aug 2018 13:53:53 -0700
parents 6c0ac4b4d761
children 36c72eb60d5b
files src/hotspot/share/include/cds.h src/hotspot/share/memory/filemap.cpp src/hotspot/share/memory/filemap.hpp src/hotspot/share/memory/metaspaceShared.cpp src/hotspot/share/prims/cdsoffsets.cpp src/hotspot/share/runtime/vmStructs.cpp src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java src/jdk.hotspot.agent/solaris/native/libsaproc/saproc.cpp test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java
diffstat 11 files changed, 261 insertions(+), 392 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/include/cds.h	Fri Aug 17 13:53:53 2018 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_INCLUDE_CDS_H
+#define SHARE_INCLUDE_CDS_H
+
+// This file declares the CDS data structures that are used by the HotSpot Serviceability Agent
+// (see C sources inside src/jdk.hotspot.agent).
+//
+// We should use only standard C types. Do not use custom types such as bool, intx,
+// etc, to avoid introducing unnecessary dependencies to other HotSpot type declarations.
+//
+// Also, this is a C header file. Do not use C++ here.
+
+#define NUM_CDS_REGIONS 9
+#define CDS_ARCHIVE_MAGIC 0xf00baba2
+#define CURRENT_CDS_ARCHIVE_VERSION 4
+#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
+  union {
+    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?
+};
+
+struct CDSFileMapHeaderBase {
+  unsigned int _magic;           // identify file type
+  int          _crc;             // header crc checksum
+  int          _version;         // must be CURRENT_CDS_ARCHIVE_VERSION
+  struct CDSFileMapRegion _space[NUM_CDS_REGIONS];
+};
+
+typedef struct CDSFileMapHeaderBase CDSFileMapHeaderBase;
+
+#endif // SHARE_INCLUDE_CDS_H
--- a/src/hotspot/share/memory/filemap.cpp	Tue Aug 21 20:29:57 2018 -0400
+++ b/src/hotspot/share/memory/filemap.cpp	Fri Aug 17 13:53:53 2018 -0700
@@ -159,8 +159,8 @@
   memset((void*)this, 0, sizeof(FileMapInfo));
   _file_offset = 0;
   _file_open = false;
-  _header = new FileMapHeader();
-  _header->_version = _invalid_version;
+  _header = (FileMapHeader*)os::malloc(sizeof(FileMapHeader), mtInternal);
+  _header->_version = INVALID_CDS_ARCHIVE_VERSION;
   _header->_has_platform_or_app_classes = true;
 }
 
@@ -173,9 +173,9 @@
   _header->populate(this, alignment);
 }
 
-void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
-  _magic = 0xf00baba2;
-  _version = _current_version;
+void FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
+  _magic = CDS_ARCHIVE_MAGIC;
+  _version = CURRENT_CDS_ARCHIVE_VERSION;
   _alignment = alignment;
   _obj_alignment = ObjectAlignmentInBytes;
   _compact_strings = CompactStrings;
@@ -493,14 +493,13 @@
 // Read the FileMapInfo information from the file.
 
 bool FileMapInfo::init_from_file(int fd) {
-  size_t sz = _header->data_size();
-  char* addr = _header->data();
-  size_t n = os::read(fd, addr, (unsigned int)sz);
+  size_t sz = sizeof(FileMapHeader);
+  size_t n = os::read(fd, _header, (unsigned int)sz);
   if (n != sz) {
     fail_continue("Unable to read the file header.");
     return false;
   }
-  if (_header->_version != current_version()) {
+  if (_header->_version != CURRENT_CDS_ARCHIVE_VERSION) {
     fail_continue("The shared archive file has the wrong version.");
     return false;
   }
@@ -521,8 +520,7 @@
   }
 
   size_t len = lseek(fd, 0, SEEK_END);
-  struct FileMapInfo::FileMapHeader::space_info* si =
-    &_header->_space[MetaspaceShared::last_valid_region];
+  CDSFileMapRegion* si = space_at(MetaspaceShared::last_valid_region);
   // The last space might be empty
   if (si->_file_offset > len || len - si->_file_offset < si->_used) {
     fail_continue("The shared archive file has been truncated.");
@@ -591,10 +589,8 @@
   _header->_paths_misc_info_size = info_size;
 
   align_file_position();
-  size_t sz = _header->data_size();
-  char* addr = _header->data();
-  write_bytes(addr, (int)sz); // skip the C++ vtable
-  write_bytes(ClassLoader::get_shared_paths_misc_info(), info_size);
+  write_bytes(_header, sizeof(FileMapHeader));
+  write_bytes(ClassLoader::get_shared_paths_misc_info(), (size_t)info_size);
   align_file_position();
 }
 
@@ -603,7 +599,7 @@
 
 void FileMapInfo::write_region(int region, char* base, size_t size,
                                bool read_only, bool allow_exec) {
-  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[region];
+  CDSFileMapRegion* si = space_at(region);
 
   if (_file_open) {
     guarantee(si->_file_offset == _file_offset, "file offset mismatch.");
@@ -628,7 +624,7 @@
   si->_allow_exec = allow_exec;
   si->_crc = ClassLoader::crc32(0, base, (jint)size);
   if (base != NULL) {
-    write_bytes_aligned(base, (int)size);
+    write_bytes_aligned(base, size);
   }
 }
 
@@ -694,9 +690,9 @@
 
 // Dump bytes to file -- at the current file position.
 
-void FileMapInfo::write_bytes(const void* buffer, int nbytes) {
+void FileMapInfo::write_bytes(const void* buffer, size_t nbytes) {
   if (_file_open) {
-    int n = ::write(_fd, buffer, nbytes);
+    size_t n = os::write(_fd, buffer, (unsigned int)nbytes);
     if (n != nbytes) {
       // It is dangerous to leave the corrupted shared archive file around,
       // close and remove the file. See bug 6372906.
@@ -732,7 +728,7 @@
 
 // Dump bytes to file -- at the current file position.
 
-void FileMapInfo::write_bytes_aligned(const void* buffer, int nbytes) {
+void FileMapInfo::write_bytes_aligned(const void* buffer, size_t nbytes) {
   align_file_position();
   write_bytes(buffer, nbytes);
   align_file_position();
@@ -756,7 +752,7 @@
 // Remap the shared readonly space to shared readwrite, private.
 bool FileMapInfo::remap_shared_readonly_as_readwrite() {
   int idx = MetaspaceShared::ro;
-  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[idx];
+  CDSFileMapRegion* si = space_at(idx);
   if (!si->_read_only) {
     // the space is already readwrite so we are done
     return true;
@@ -808,7 +804,7 @@
 
 char* FileMapInfo::map_region(int i, char** top_ret) {
   assert(!MetaspaceShared::is_heap_region(i), "sanity");
-  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
+  CDSFileMapRegion* si = space_at(i);
   size_t used = si->_used;
   size_t alignment = os::vm_allocation_granularity();
   size_t size = align_up(used, alignment);
@@ -875,7 +871,7 @@
         narrow_oop_shift() != Universe::narrow_oop_shift() ||
         narrow_klass_base() != Universe::narrow_klass_base() ||
         narrow_klass_shift() != Universe::narrow_klass_shift()) {
-      if (log_is_enabled(Info, cds) && _header->_space[MetaspaceShared::first_string]._used > 0) {
+      if (log_is_enabled(Info, cds) && space_at(MetaspaceShared::first_string)->_used > 0) {
         log_info(cds)("Cached heap data from the CDS archive is being ignored. "
                       "The current CompressedOops/CompressedClassPointers encoding differs from "
                       "that archived due to heap size change. The archive was dumped using max heap "
@@ -906,7 +902,7 @@
       }
     }
   } else {
-    if (log_is_enabled(Info, cds) && _header->_space[MetaspaceShared::first_string]._used > 0) {
+    if (log_is_enabled(Info, cds) && space_at(MetaspaceShared::first_string)->_used > 0) {
       log_info(cds)("Cached heap data from the CDS archive is being ignored. UseG1GC, "
                     "UseCompressedOops and UseCompressedClassPointers are required.");
     }
@@ -924,12 +920,12 @@
 bool FileMapInfo::map_heap_data(MemRegion **heap_mem, int first,
                                 int max, int* num, bool is_open_archive) {
   MemRegion * regions = new MemRegion[max];
-  struct FileMapInfo::FileMapHeader::space_info* si;
+  CDSFileMapRegion* si;
   int region_num = 0;
 
   for (int i = first;
            i < first + max; i++) {
-    si = &_header->_space[i];
+    si = space_at(i);
     size_t used = si->_used;
     if (used > 0) {
       size_t size = used;
@@ -963,7 +959,7 @@
   // for mapped regions as they are part of the reserved java heap, which is
   // already recorded.
   for (int i = 0; i < region_num; i++) {
-    si = &_header->_space[first + 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,
@@ -1029,7 +1025,7 @@
     return true;
   }
 
-  size_t sz = _header->_space[i]._used;
+  size_t sz = space_at(i)->_used;
 
   if (sz == 0) {
     return true; // no data
@@ -1042,7 +1038,7 @@
   }
   const char* buf = _header->region_addr(i);
   int crc = ClassLoader::crc32(0, buf, (jint)sz);
-  if (crc != _header->_space[i]._crc) {
+  if (crc != space_at(i)->_crc) {
     fail_continue("Checksum verification failed.");
     return false;
   }
@@ -1053,7 +1049,7 @@
 
 void FileMapInfo::unmap_region(int i) {
   assert(!MetaspaceShared::is_heap_region(i), "sanity");
-  struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
+  CDSFileMapRegion* si = space_at(i);
   size_t used = si->_used;
   size_t size = align_up(used, os::vm_allocation_granularity());
 
@@ -1111,7 +1107,7 @@
   return true;
 }
 
-char* FileMapInfo::FileMapHeader::region_addr(int idx) {
+char* FileMapHeader::region_addr(int idx) {
   if (MetaspaceShared::is_heap_region(idx)) {
     return _space[idx]._used > 0 ?
              (char*)((void*)CompressedOops::decode_not_null((narrowOop)_space[idx]._addr._offset)) : NULL;
@@ -1120,19 +1116,19 @@
   }
 }
 
-int FileMapInfo::FileMapHeader::compute_crc() {
-  char* header = data();
+int FileMapHeader::compute_crc() {
+  char* start = (char*)this;
   // start computing from the field after _crc
-  char* buf = (char*)&_crc + sizeof(int);
-  size_t sz = data_size() - (buf - header);
+  char* buf = (char*)&_crc + sizeof(_crc);
+  size_t sz = sizeof(FileMapHeader) - (buf - start);
   int crc = ClassLoader::crc32(0, buf, (jint)sz);
   return crc;
 }
 
 // This function should only be called during run time with UseSharedSpaces enabled.
-bool FileMapInfo::FileMapHeader::validate() {
+bool FileMapHeader::validate() {
   if (VerifySharedSpaces && compute_crc() != _crc) {
-    fail_continue("Header checksum verification failed.");
+    FileMapInfo::fail_continue("Header checksum verification failed.");
     return false;
   }
 
@@ -1141,11 +1137,11 @@
     return false;
   }
 
-  if (_version != current_version()) {
+  if (_version != CURRENT_CDS_ARCHIVE_VERSION) {
     FileMapInfo::fail_continue("The shared archive file is the wrong version.");
     return false;
   }
-  if (_magic != (int)0xf00baba2) {
+  if (_magic != CDS_ARCHIVE_MAGIC) {
     FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
     return false;
   }
@@ -1221,7 +1217,7 @@
          idx == MetaspaceShared::mc ||
          idx == MetaspaceShared::md, "invalid region index");
   char* base = _header->region_addr(idx);
-  if (p >= base && p < base + _header->_space[idx]._used) {
+  if (p >= base && p < base + space_at(idx)->_used) {
     return true;
   }
   return false;
@@ -1230,7 +1226,7 @@
 void FileMapInfo::print_shared_spaces() {
   tty->print_cr("Shared Spaces:");
   for (int i = 0; i < MetaspaceShared::n_regions; i++) {
-    struct FileMapInfo::FileMapHeader::space_info* si = &_header->_space[i];
+    CDSFileMapRegion* si = space_at(i);
     char *base = _header->region_addr(i);
     tty->print("  %s " INTPTR_FORMAT "-" INTPTR_FORMAT,
                         shared_region_name[i],
@@ -1247,7 +1243,7 @@
       char *addr = map_info->_header->region_addr(i);
       if (addr != NULL && !MetaspaceShared::is_heap_region(i)) {
         map_info->unmap_region(i);
-        map_info->_header->_space[i]._addr._base = NULL;
+        map_info->space_at(i)->_addr._base = NULL;
       }
     }
     // Dealloc the archive heap regions only without unmapping. The regions are part
--- a/src/hotspot/share/memory/filemap.hpp	Tue Aug 21 20:29:57 2018 -0400
+++ b/src/hotspot/share/memory/filemap.hpp	Fri Aug 17 13:53:53 2018 -0700
@@ -26,6 +26,7 @@
 #define SHARE_VM_MEMORY_FILEMAP_HPP
 
 #include "classfile/classLoader.hpp"
+#include "include/cds.h"
 #include "memory/metaspaceShared.hpp"
 #include "memory/metaspace.hpp"
 #include "memory/universe.hpp"
@@ -87,17 +88,86 @@
   }
 };
 
+struct FileMapHeader : public CDSFileMapHeaderBase {
+  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
+  uintx  _max_heap_size;            // java max heap size during dumping
+  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;
+  char*   _read_only_tables_start;
+  address _cds_i2i_entry_code_buffers;
+  size_t  _cds_i2i_entry_code_buffers_size;
+  size_t  _core_spaces_size;        // number of bytes allocated by the core spaces
+                                    // (mc, md, ro, rw and od).
+
+  // 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
+
+  // The _paths_misc_info is a variable-size structure that records "miscellaneous"
+  // information during dumping. It is generated and validated by the
+  // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp for
+  // detailed description.
+  //
+  // The _paths_misc_info data is stored as a byte array in the archive file header,
+  // immediately after the _header field. This information is used only when
+  // checking the validity of the archive and is deallocated after the archive is loaded.
+  //
+  // Note that the _paths_misc_info does NOT include information for JAR files
+  // that existed during dump time. Their information is stored in _shared_path_table.
+  int _paths_misc_info_size;
+
+  // The following is a table of all the class path entries that were used
+  // during dumping. At run time, we require these files to exist and have the same
+  // size/modification time, or else the archive will refuse to load.
+  //
+  // All of these entries must be JAR files. The dumping process would fail if a non-empty
+  // directory was specified in the classpaths. If an empty directory was specified
+  // it is checked by the _paths_misc_info as described above.
+  //
+  // FIXME -- if JAR files in the tail of the list were specified but not used during dumping,
+  // they should be removed from this table, to save space and to avoid spurious
+  // loading failures during runtime.
+  int _shared_path_table_size;
+  size_t _shared_path_entry_size;
+  Array<u8>* _shared_path_table;
+
+  jshort _app_class_paths_start_index;  // Index of first app classpath entry
+  jshort _app_module_paths_start_index; // Index of first module path entry
+  jshort _max_used_path_index;          // max path index referenced during CDS dump
+  bool   _verify_local;                 // BytecodeVerificationLocal setting
+  bool   _verify_remote;                // BytecodeVerificationRemote setting
+  bool   _has_platform_or_app_classes;  // Archive contains app classes
+
+  void set_has_platform_or_app_classes(bool v) {
+    _has_platform_or_app_classes = v;
+  }
+  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; }
+
+  char* region_addr(int idx);
+
+  bool validate();
+  void populate(FileMapInfo* info, size_t alignment);
+  int compute_crc();
+};
+
+
 class FileMapInfo : public CHeapObj<mtInternal> {
 private:
   friend class ManifestStream;
   friend class VMStructs;
-  enum {
-    _invalid_version = -1,
-    _current_version = 3
-  };
+  friend struct FileMapHeader;
 
-  bool  _file_open;
-  int   _fd;
+  bool    _file_open;
+  int     _fd;
   size_t  _file_offset;
 
 private:
@@ -116,100 +186,7 @@
     // methods, we would get sizeof(FileMapHeaderBase) == 1 with gcc.
     intx _dummy;
   };
-  struct FileMapHeader : FileMapHeaderBase {
-    // Use data() and data_size() to memcopy to/from the FileMapHeader. We need to
-    // avoid read/writing the C++ vtable pointer.
-    static size_t data_size() {
-      return sizeof(FileMapHeader) - sizeof(FileMapInfo::FileMapHeaderBase);
-    }
-    char* data() {
-      return ((char*)this) + sizeof(FileMapHeaderBase);
-    }
 
-    int    _magic;                    // identify file type.
-    int    _crc;                      // header crc checksum.
-    int    _version;                  // (from enum, above.)
-    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
-    uintx  _max_heap_size;            // java max heap size during dumping
-    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;
-    char*   _read_only_tables_start;
-    address _cds_i2i_entry_code_buffers;
-    size_t  _cds_i2i_entry_code_buffers_size;
-    size_t  _core_spaces_size;        // number of bytes allocated by the core spaces
-                                      // (mc, md, ro, rw and od).
-    struct space_info {
-      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
-        intx   _offset;      // offset from the compressed oop encoding base, only used
-                             // by archive heap space
-      } _addr;
-      size_t _used;          // for setting space top on read
-      bool   _read_only;     // read only space?
-      bool   _allow_exec;    // executable code in space?
-    } _space[MetaspaceShared::n_regions];
-
-    // 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
-
-    // The _paths_misc_info is a variable-size structure that records "miscellaneous"
-    // information during dumping. It is generated and validated by the
-    // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp for
-    // detailed description.
-    //
-    // The _paths_misc_info data is stored as a byte array in the archive file header,
-    // immediately after the _header field. This information is used only when
-    // checking the validity of the archive and is deallocated after the archive is loaded.
-    //
-    // Note that the _paths_misc_info does NOT include information for JAR files
-    // that existed during dump time. Their information is stored in _shared_path_table.
-    int _paths_misc_info_size;
-
-    // The following is a table of all the class path entries that were used
-    // during dumping. At run time, we require these files to exist and have the same
-    // size/modification time, or else the archive will refuse to load.
-    //
-    // All of these entries must be JAR files. The dumping process would fail if a non-empty
-    // directory was specified in the classpaths. If an empty directory was specified
-    // it is checked by the _paths_misc_info as described above.
-    //
-    // FIXME -- if JAR files in the tail of the list were specified but not used during dumping,
-    // they should be removed from this table, to save space and to avoid spurious
-    // loading failures during runtime.
-    int _shared_path_table_size;
-    size_t _shared_path_entry_size;
-    Array<u8>* _shared_path_table;
-
-    jshort _app_class_paths_start_index;  // Index of first app classpath entry
-    jshort _app_module_paths_start_index; // Index of first module path entry
-    jshort _max_used_path_index;          // max path index referenced during CDS dump
-    bool   _verify_local;                 // BytecodeVerificationLocal setting
-    bool   _verify_remote;                // BytecodeVerificationRemote setting
-    bool   _has_platform_or_app_classes;  // Archive contains app classes
-
-    void set_has_platform_or_app_classes(bool v) {
-      _has_platform_or_app_classes = v;
-    }
-    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; }
-
-    char* region_addr(int idx);
-
-    bool validate();
-    void populate(FileMapInfo* info, size_t alignment);
-    int compute_crc();
-  };
 
   FileMapHeader * _header;
 
@@ -227,7 +204,6 @@
   FileMapInfo();
   ~FileMapInfo();
 
-  static int current_version()        { return _current_version; }
   int    compute_header_crc()         { return _header->compute_crc(); }
   void   set_header_crc(int crc)      { _header->_crc = crc; }
   void   populate_header(size_t alignment);
@@ -278,8 +254,8 @@
                      bool read_only, bool allow_exec);
   size_t write_archive_heap_regions(GrowableArray<MemRegion> *heap_mem,
                                     int first_region_id, int max_num_regions);
-  void  write_bytes(const void* buffer, int count);
-  void  write_bytes_aligned(const void* buffer, int count);
+  void  write_bytes(const void* buffer, size_t count);
+  void  write_bytes_aligned(const void* buffer, size_t count);
   char* map_region(int i, char** top_ret);
   void  map_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
   void  fixup_mapped_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
@@ -332,6 +308,11 @@
                       bool is_open = false) NOT_CDS_JAVA_HEAP_RETURN_(false);
   bool  verify_mapped_heap_regions(int first, int num) NOT_CDS_JAVA_HEAP_RETURN_(false);
   void  dealloc_archive_heap_regions(MemRegion* regions, int num) NOT_CDS_JAVA_HEAP_RETURN;
+
+  CDSFileMapRegion* space_at(int i) {
+    assert(i >= 0 && i < NUM_CDS_REGIONS, "invalid region");
+    return &_header->_space[i];
+  }
 };
 
 #endif // SHARE_VM_MEMORY_FILEMAP_HPP
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Tue Aug 21 20:29:57 2018 -0400
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Fri Aug 17 13:53:53 2018 -0700
@@ -333,7 +333,7 @@
     int size = FileMapInfo::get_number_of_shared_paths();
     if (size > 0) {
       SystemDictionaryShared::allocate_shared_data_arrays(size, THREAD);
-      FileMapInfo::FileMapHeader* header = FileMapInfo::current_info()->header();
+      FileMapHeader* header = FileMapInfo::current_info()->header();
       ClassLoaderExt::init_paths_start_index(header->_app_class_paths_start_index);
       ClassLoaderExt::init_app_module_paths_start_index(header->_app_module_paths_start_index);
     }
--- a/src/hotspot/share/prims/cdsoffsets.cpp	Tue Aug 21 20:29:57 2018 -0400
+++ b/src/hotspot/share/prims/cdsoffsets.cpp	Fri Aug 17 13:53:53 2018 -0700
@@ -42,17 +42,17 @@
 #define ADD_NEXT(list, name, value) \
   list->add_end(new CDSOffsets(name, value, NULL))
 
-#define CREATE_OFFSET_MAPS                                                                                  \
-    _all = new CDSOffsets("size_t_size", sizeof(size_t), NULL);                                             \
-    ADD_NEXT(_all, "FileMapHeader::_magic", offset_of(FileMapInfo::FileMapHeader, _magic));                 \
-    ADD_NEXT(_all, "FileMapHeader::_crc", offset_of(FileMapInfo::FileMapHeader, _crc));                     \
-    ADD_NEXT(_all, "FileMapHeader::_version", offset_of(FileMapInfo::FileMapHeader, _version));             \
-    ADD_NEXT(_all, "FileMapHeader::_space[0]", offset_of(FileMapInfo::FileMapHeader, _space));              \
-    ADD_NEXT(_all, "space_info::_crc", offset_of(FileMapInfo::FileMapHeader::space_info, _crc));            \
-    ADD_NEXT(_all, "space_info::_used", offset_of(FileMapInfo::FileMapHeader::space_info, _used));          \
-    ADD_NEXT(_all, "FileMapHeader::_paths_misc_info_size", offset_of(FileMapInfo::FileMapHeader, _paths_misc_info_size)); \
-    ADD_NEXT(_all, "file_header_size", sizeof(FileMapInfo::FileMapHeader));                                 \
-    ADD_NEXT(_all, "space_info_size", sizeof(FileMapInfo::FileMapHeader::space_info));
+#define CREATE_OFFSET_MAPS                                                                  \
+    _all = new CDSOffsets("size_t_size", sizeof(size_t), NULL);                             \
+    ADD_NEXT(_all, "FileMapHeader::_magic", offset_of(FileMapHeader, _magic));              \
+    ADD_NEXT(_all, "FileMapHeader::_crc", offset_of(FileMapHeader, _crc));                  \
+    ADD_NEXT(_all, "FileMapHeader::_version", offset_of(FileMapHeader, _version));          \
+    ADD_NEXT(_all, "FileMapHeader::_space[0]", offset_of(FileMapHeader, _space));           \
+    ADD_NEXT(_all, "CDSFileMapRegion::_crc", offset_of(CDSFileMapRegion, _crc));            \
+    ADD_NEXT(_all, "CDSFileMapRegion::_used", offset_of(CDSFileMapRegion, _used));          \
+    ADD_NEXT(_all, "FileMapHeader::_paths_misc_info_size", offset_of(FileMapHeader, _paths_misc_info_size)); \
+    ADD_NEXT(_all, "file_header_size", sizeof(FileMapHeader));                              \
+    ADD_NEXT(_all, "CDSFileMapRegion_size", sizeof(CDSFileMapRegion));
 
 int CDSOffsets::find_offset(const char* name) {
   if (_all == NULL) {
--- a/src/hotspot/share/runtime/vmStructs.cpp	Tue Aug 21 20:29:57 2018 -0400
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Fri Aug 17 13:53:53 2018 -0700
@@ -1095,11 +1095,11 @@
   /* FileMapInfo fields (CDS archive related) */                                                                                     \
   /********************************************/                                                                                     \
                                                                                                                                      \
-  CDS_ONLY(nonstatic_field(FileMapInfo,                            _header,                   FileMapInfo::FileMapHeader*))          \
-  CDS_ONLY(   static_field(FileMapInfo,                            _current_info,             FileMapInfo*))                         \
-  CDS_ONLY(nonstatic_field(FileMapInfo::FileMapHeader,             _space[0],                 FileMapInfo::FileMapHeader::space_info))\
-  CDS_ONLY(nonstatic_field(FileMapInfo::FileMapHeader::space_info, _addr._base,               char*))                                \
-  CDS_ONLY(nonstatic_field(FileMapInfo::FileMapHeader::space_info, _used,                     size_t))                               \
+  CDS_ONLY(nonstatic_field(FileMapInfo,        _header,                   FileMapHeader*))                                           \
+  CDS_ONLY(   static_field(FileMapInfo,        _current_info,             FileMapInfo*))                                             \
+  CDS_ONLY(nonstatic_field(FileMapHeader,      _space[0],                 CDSFileMapRegion))                                         \
+  CDS_ONLY(nonstatic_field(CDSFileMapRegion,   _addr._base,               char*))                                                    \
+  CDS_ONLY(nonstatic_field(CDSFileMapRegion,   _used,                     size_t))                                                   \
                                                                                                                                      \
   /******************/                                                                                                               \
   /* VMError fields */                                                                                                               \
@@ -1978,9 +1978,8 @@
   declare_toplevel_type(Annotations*)                                     \
   declare_type(OopMapValue, StackObj)                                     \
   declare_type(FileMapInfo, CHeapObj<mtInternal>)                         \
-  declare_type(FileMapInfo::FileMapHeaderBase, CHeapObj<mtClass>)         \
-  declare_type(FileMapInfo::FileMapHeader, FileMapInfo::FileMapHeaderBase)\
-  declare_toplevel_type(FileMapInfo::FileMapHeader::space_info)           \
+  declare_toplevel_type(FileMapHeader)                                    \
+  declare_toplevel_type(CDSFileMapRegion)                                 \
                                                                           \
   /************/                                                          \
   /* GC types */                                                          \
--- a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c	Tue Aug 21 20:29:57 2018 -0400
+++ b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_core.c	Fri Aug 17 13:53:53 2018 -0700
@@ -32,6 +32,7 @@
 #include <link.h>
 #include "libproc_impl.h"
 #include "salibelf.h"
+#include "cds.h"
 
 // This file has the libproc implementation to read core files.
 // For live processes, refer to ps_proc.c. Portions of this is adapted
@@ -203,65 +204,6 @@
 // PROT_READ pages. These pages are not dumped into core dump.
 // With this workaround, these pages are read from classes.jsa.
 
-// FIXME: !HACK ALERT!
-// The format of sharing achive file header is needed to read shared heap
-// file mappings. For now, I am hard coding portion of FileMapHeader here.
-// Refer to filemap.hpp.
-
-// FileMapHeader describes the shared space data in the file to be
-// 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.
-
-#define NUM_SHARED_MAPS 9
-
-// Refer to FileMapInfo::_current_version in filemap.hpp
-#define CURRENT_ARCHIVE_VERSION 3
-
-typedef unsigned char* address;
-typedef uintptr_t      uintx;
-typedef intptr_t       intx;
-
-struct FileMapHeader {
-  int     _magic;                   // identify file type.
-  int     _crc;                     // header crc checksum.
-  int     _version;                 // (from enum, above.)
-  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
-  uintx   _max_heap_size;           // java max heap size during dumping
-  int     _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;
-  size_t  _core_spaces_size;        // number of bytes allocated by the core spaces
-                                    // (mc, md, ro, rw and od).
-
-
-  struct space_info {
-    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
-      intx   _offset;      // offset from the compressed oop encoding base, only used
-                           // by archive heap space
-    } _addr;
-    size_t _used;          // for setting space top on read
-    // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
-    // the C type matching the C++ bool type on any given platform.
-    // We assume the corresponding C type is char but licensees
-    // may need to adjust the type of these fields.
-    char   _read_only;     // read only space?
-    char   _allow_exec;    // executable code in space?
-  } _space[NUM_SHARED_MAPS];
-
-  // Ignore the rest of the FileMapHeader. We don't need those fields here.
-};
-
 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
   jboolean i;
   if (ps_pdread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
@@ -317,7 +259,7 @@
     const char *jvm_name = 0;
     if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
       char classes_jsa[PATH_MAX];
-      struct FileMapHeader header;
+      CDSFileMapHeaderBase header;
       int fd = -1;
       int m = 0;
       size_t n = 0;
@@ -374,34 +316,34 @@
         print_debug("opened %s\n", classes_jsa);
       }
 
-      // read FileMapHeader from the file
-      memset(&header, 0, sizeof(struct FileMapHeader));
-      if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
-           != sizeof(struct FileMapHeader)) {
+      // read CDSFileMapHeaderBase from the file
+      memset(&header, 0, sizeof(CDSFileMapHeaderBase));
+      if ((n = read(fd, &header, sizeof(CDSFileMapHeaderBase)))
+           != sizeof(CDSFileMapHeaderBase)) {
         print_debug("can't read shared archive file map header from %s\n", classes_jsa);
         close(fd);
         return false;
       }
 
       // check file magic
-      if (header._magic != 0xf00baba2) {
-        print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
-                     classes_jsa, header._magic);
+      if (header._magic != CDS_ARCHIVE_MAGIC) {
+        print_debug("%s has bad shared archive file magic number 0x%x, expecting 0x%x\n",
+                    classes_jsa, header._magic, CDS_ARCHIVE_MAGIC);
         close(fd);
         return false;
       }
 
       // check version
-      if (header._version != CURRENT_ARCHIVE_VERSION) {
+      if (header._version != CURRENT_CDS_ARCHIVE_VERSION) {
         print_debug("%s has wrong shared archive file version %d, expecting %d\n",
-                     classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
+                     classes_jsa, header._version, CURRENT_CDS_ARCHIVE_VERSION);
         close(fd);
         return false;
       }
 
       ph->core->classes_jsa_fd = fd;
       // add read-only maps from classes.jsa to the list of maps
-      for (m = 0; m < NUM_SHARED_MAPS; m++) {
+      for (m = 0; m < NUM_CDS_REGIONS; m++) {
         if (header._space[m]._read_only) {
           base = (uintptr_t) header._space[m]._addr._base;
           // no need to worry about the fractional pages at-the-end.
--- a/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c	Tue Aug 21 20:29:57 2018 -0400
+++ b/src/jdk.hotspot.agent/macosx/native/libsaproc/ps_core.c	Fri Aug 17 13:53:53 2018 -0700
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include "libproc_impl.h"
+#include "cds.h"
 
 #ifdef __APPLE__
 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
@@ -204,66 +205,6 @@
 // PROT_READ pages. These pages are not dumped into core dump.
 // With this workaround, these pages are read from classes.jsa.
 
-// FIXME: !HACK ALERT!
-// The format of sharing achive file header is needed to read shared heap
-// file mappings. For now, I am hard coding portion of FileMapHeader here.
-// Refer to filemap.hpp.
-
-// FileMapHeader describes the shared space data in the file to be
-// 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.
-
-#define NUM_SHARED_MAPS 9
-
-// Refer to FileMapInfo::_current_version in filemap.hpp
-#define CURRENT_ARCHIVE_VERSION 3
-
-typedef unsigned char* address;
-typedef uintptr_t      uintx;
-typedef intptr_t       intx;
-
-
-struct FileMapHeader {
-  int     _magic;                   // identify file type.
-  int     _crc;                     // header crc checksum.
-  int     _version;                 // (from enum, above.)
-  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
-  uintx   _max_heap_size;           // java max heap size during dumping
-  int     _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;
-  size_t  _core_spaces_size;        // number of bytes allocated by the core spaces
-                                    // (mc, md, ro, rw and od).
-
-
-  struct space_info {
-    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
-      intx   _offset;      // offset from the compressed oop encoding base, only used
-                           // by archive heap space
-    } _addr;
-    size_t _used;          // for setting space top on read
-    // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
-    // the C type matching the C++ bool type on any given platform.
-    // We assume the corresponding C type is char but licensees
-    // may need to adjust the type of these fields.
-    char   _read_only;     // read only space?
-    char   _allow_exec;    // executable code in space?
-  } _space[NUM_SHARED_MAPS];
-
-  // Ignore the rest of the FileMapHeader. We don't need those fields here.
-};
-
 static bool read_jboolean(struct ps_prochandle* ph, uintptr_t addr, jboolean* pvalue) {
   jboolean i;
   if (ps_pread(ph, (psaddr_t) addr, &i, sizeof(i)) == PS_OK) {
@@ -326,7 +267,7 @@
     const char *jvm_name = 0;
     if ((jvm_name = strstr(lib->name, LIBJVM_NAME)) != 0) {
       char classes_jsa[PATH_MAX];
-      struct FileMapHeader header;
+      CDSFileMapHeaderBase header;
       int fd = -1;
       uintptr_t base = 0, useSharedSpacesAddr = 0;
       uintptr_t sharedArchivePathAddrAddr = 0, sharedArchivePathAddr = 0;
@@ -380,34 +321,34 @@
         print_debug("opened %s\n", classes_jsa);
       }
 
-      // read FileMapHeader from the file
-      memset(&header, 0, sizeof(struct FileMapHeader));
-      if ((n = read(fd, &header, sizeof(struct FileMapHeader)))
-           != sizeof(struct FileMapHeader)) {
+      // read CDSFileMapHeaderBase from the file
+      memset(&header, 0, sizeof(CDSFileMapHeaderBase));
+      if ((n = read(fd, &header, sizeof(CDSFileMapHeaderBase)))
+           != sizeof(CDSFileMapHeaderBase)) {
         print_debug("can't read shared archive file map header from %s\n", classes_jsa);
         close(fd);
         return false;
       }
 
       // check file magic
-      if (header._magic != 0xf00baba2) {
-        print_debug("%s has bad shared archive file magic number 0x%x, expecing 0xf00baba2\n",
-                     classes_jsa, header._magic);
+      if (header._magic != CDS_ARCHIVE_MAGIC) {
+        print_debug("%s has bad shared archive file magic number 0x%x, expecting 0x%x\n",
+                    classes_jsa, header._magic, CDS_ARCHIVE_MAGIC);
         close(fd);
         return false;
       }
 
       // check version
-      if (header._version != CURRENT_ARCHIVE_VERSION) {
+      if (header._version != CURRENT_CDS_ARCHIVE_VERSION) {
         print_debug("%s has wrong shared archive file version %d, expecting %d\n",
-                     classes_jsa, header._version, CURRENT_ARCHIVE_VERSION);
+                     classes_jsa, header._version, CURRENT_CDS_ARCHIVE_VERSION);
         close(fd);
         return false;
       }
 
       ph->core->classes_jsa_fd = fd;
       // add read-only maps from classes.jsa to the list of maps
-      for (m = 0; m < NUM_SHARED_MAPS; m++) {
+      for (m = 0; m < NUM_CDS_REGIONS; m++) {
         if (header._space[m]._read_only) {
           base = (uintptr_t) header._space[m]._addr._base;
           // no need to worry about the fractional pages at-the-end.
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java	Tue Aug 21 20:29:57 2018 -0400
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/memory/FileMapInfo.java	Fri Aug 17 13:53:53 2018 -0700
@@ -63,13 +63,13 @@
     headerValue = headerAddress.getAddressAt(0);
 
     // FileMapHeader
-    type = db.lookupType("FileMapInfo::FileMapHeader");
+    type = db.lookupType("FileMapHeader");
     AddressField spaceField = type.getAddressField("_space[0]");
     Address spaceValue = headerValue.addOffsetTo(type.getField("_space[0]").getOffset());
     mdSpaceValue = spaceValue.addOffsetTo(3 * spaceField.getSize());
 
     // SpaceInfo
-    type = db.lookupType("FileMapInfo::FileMapHeader::space_info");
+    type = db.lookupType("CDSFileMapRegion");
     long mdRegionBaseAddressOffset = type.getField("_addr._base").getOffset();
     mdRegionBaseAddress = (mdSpaceValue.addOffsetTo(mdRegionBaseAddressOffset)).getAddressAt(0);
     long mdRegionSizeOffset = type.getField("_used").getOffset();
--- a/src/jdk.hotspot.agent/solaris/native/libsaproc/saproc.cpp	Tue Aug 21 20:29:57 2018 -0400
+++ b/src/jdk.hotspot.agent/solaris/native/libsaproc/saproc.cpp	Fri Aug 17 13:53:53 2018 -0700
@@ -31,6 +31,7 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <errno.h>
+#include "cds.h"
 
 #define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; }
 #define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;}
@@ -173,7 +174,7 @@
   int classes_jsa_fd = env->GetIntField(this_obj, classes_jsa_fd_ID);
   if (classes_jsa_fd != -1) {
     close(classes_jsa_fd);
-    struct FileMapHeader* pheader = (struct FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
+    CDSFileMapHeaderBase* pheader = (CDSFileMapHeaderBase*) env->GetLongField(this_obj, p_file_map_header_ID);
     if (pheader != NULL) {
       free(pheader);
     }
@@ -484,67 +485,13 @@
   return(fill_cframe_list(cd, regs, argc, argv));
 }
 
-// part of the class sharing workaround
-
-// FIXME: !!HACK ALERT!!
-
-// The format of sharing achive file header is needed to read shared heap
-// file mappings. For now, I am hard coding portion of FileMapHeader here.
-// Refer to filemap.hpp.
-
-// FileMapHeader describes the shared space data in the file to be
-// 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.
-
-const int NUM_SHARED_MAPS = 9;
-
-// Refer to FileMapInfo::_current_version in filemap.hpp
-const int CURRENT_ARCHIVE_VERSION = 3;
-
-typedef unsigned char* address;
-typedef uintptr_t      uintx;
-typedef intptr_t       intx;
-
-struct FileMapHeader {
-  int     _magic;                   // identify file type.
-  int     _crc;                     // header crc checksum.
-  int     _version;                 // (from enum, above.)
-  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
-  uintx   _max_heap_size;           // java max heap size during dumping
-  int     _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;
-  size_t  _core_spaces_size;        // number of bytes allocated by the core spaces
-                                    // (mc, md, ro, rw and od).
-
-
-  struct space_info {
-    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
-      intx   _offset;      // offset from the compressed oop encoding base, only used
-                           // by archive heap space
-    } _addr;
-    size_t _used;          // for setting space top on read
-    // 4991491 NOTICE These are C++ bool's in filemap.hpp and must match up with
-    // the C type matching the C++ bool type on any given platform.
-    // We assume the corresponding C type is char but licensees
-    // may need to adjust the type of these fields.
-    char   _read_only;     // read only space?
-    char   _allow_exec;    // executable code in space?
-  } _space[NUM_SHARED_MAPS];
-
-// Ignore the rest of the FileMapHeader. We don't need those fields here.
-};
+//---------------------------------------------------------------
+// Part of the class sharing workaround:
+//
+// With class sharing, pages are mapped from classes.jsa file.
+// The read-only class sharing pages are mapped as MAP_SHARED,
+// PROT_READ pages. These pages are not dumped into core dump.
+// With this workaround, these pages are read from classes.jsa.
 
 static bool
 read_jboolean(struct ps_prochandle* ph, psaddr_t addr, jboolean* pvalue) {
@@ -662,16 +609,16 @@
   }
 
   // parse classes.jsa
-  struct FileMapHeader* pheader = (struct FileMapHeader*) malloc(sizeof(struct FileMapHeader));
+  CDSFileMapHeaderBase* pheader = (CDSFileMapHeaderBase*) malloc(sizeof(CDSFileMapHeaderBase));
   if (pheader == NULL) {
     close(fd);
     THROW_NEW_DEBUGGER_EXCEPTION_("can't allocate memory for shared file map header", 1);
   }
 
-  memset(pheader, 0, sizeof(struct FileMapHeader));
-  // read FileMapHeader
-  size_t n = read(fd, pheader, sizeof(struct FileMapHeader));
-  if (n != sizeof(struct FileMapHeader)) {
+  memset(pheader, 0, sizeof(CDSFileMapHeaderBase));
+  // read CDSFileMapHeaderBase
+  size_t n = read(fd, pheader, sizeof(CDSFileMapHeaderBase));
+  if (n != sizeof(CDSFileMapHeaderBase)) {
     char errMsg[ERR_MSG_SIZE];
     sprintf(errMsg, "unable to read shared archive file map header from %s", classes_jsa);
     close(fd);
@@ -680,27 +627,27 @@
   }
 
   // check file magic
-  if (pheader->_magic != 0xf00baba2) {
+  if (pheader->_magic != CDS_ARCHIVE_MAGIC) {
     char errMsg[ERR_MSG_SIZE];
-    sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0xf00baba2",
-                   classes_jsa, pheader->_magic);
+    sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0x%x",
+            classes_jsa, pheader->_magic, CDS_ARCHIVE_MAGIC);
     close(fd);
     free(pheader);
     THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
   }
 
   // check version
-  if (pheader->_version != CURRENT_ARCHIVE_VERSION) {
+  if (pheader->_version != CURRENT_CDS_ARCHIVE_VERSION) {
     char errMsg[ERR_MSG_SIZE];
     sprintf(errMsg, "%s has wrong shared archive version %d, expecting %d",
-                   classes_jsa, pheader->_version, CURRENT_ARCHIVE_VERSION);
+                   classes_jsa, pheader->_version, CURRENT_CDS_ARCHIVE_VERSION);
     close(fd);
     free(pheader);
     THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
   }
 
   if (_libsaproc_debug) {
-    for (int m = 0; m < NUM_SHARED_MAPS; m++) {
+    for (int m = 0; m < NUM_CDS_REGIONS; m++) {
        print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
           pheader->_space[m]._file_offset, pheader->_space[m]._addr._base,
           pheader->_space[m]._used, pheader->_space[m]._read_only);
@@ -1091,10 +1038,10 @@
     if (classes_jsa_fd != -1 && address != (jlong)0) {
       print_debug("read failed at 0x%lx, attempting shared heap area\n", (long) address);
 
-      struct FileMapHeader* pheader = (struct FileMapHeader*) env->GetLongField(this_obj, p_file_map_header_ID);
+      CDSFileMapHeaderBase* pheader = (CDSFileMapHeaderBase*) env->GetLongField(this_obj, p_file_map_header_ID);
       // walk through the shared mappings -- we just have 9 of them.
       // so, linear walking is okay.
-      for (int m = 0; m < NUM_SHARED_MAPS; m++) {
+      for (int m = 0; m < NUM_CDS_REGIONS; m++) {
 
         // We can skip the non-read-only maps. These are mapped as MAP_PRIVATE
         // and hence will be read by libproc. Besides, the file copy may be
--- a/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java	Tue Aug 21 20:29:57 2018 -0400
+++ b/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java	Fri Aug 17 13:53:53 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,11 +62,11 @@
 public class SharedArchiveConsistency {
     public static WhiteBox wb;
     public static int offset_magic;    // FileMapHeader::_magic
-    public static int sp_offset_crc;   // FileMapHeader::space_info::_crc
+    public static int sp_offset_crc;   // CDSFileMapRegion::_crc
     public static int file_header_size = -1;// total size of header, variant, need calculation
-    public static int space_info_size; // size of space_info
-    public static int sp_offset;       // offset of FileMapHeader::space_info
-    public static int sp_used_offset;  // offset of space_info::_used
+    public static int CDSFileMapRegion_size; // size of CDSFileMapRegion
+    public static int sp_offset;       // offset of CDSFileMapRegion
+    public static int sp_used_offset;  // offset of CDSFileMapRegion::_used
     public static int size_t_size;     // size of size_t
 
     public static File jsa;        // will be updated during test
@@ -83,7 +83,7 @@
     public static void getFileOffsetInfo() throws Exception {
         wb = WhiteBox.getWhiteBox();
         offset_magic = wb.getOffsetForName("FileMapHeader::_magic");
-        sp_offset_crc = wb.getOffsetForName("space_info::_crc");
+        sp_offset_crc = wb.getOffsetForName("CDSFileMapRegion::_crc");
         try {
             int nonExistOffset = wb.getOffsetForName("FileMapHeader::_non_exist_offset");
             System.exit(-1); // should fail
@@ -92,9 +92,9 @@
         }
 
         sp_offset = wb.getOffsetForName("FileMapHeader::_space[0]") - offset_magic;
-        sp_used_offset = wb.getOffsetForName("space_info::_used") - sp_offset_crc;
+        sp_used_offset = wb.getOffsetForName("CDSFileMapRegion::_used") - sp_offset_crc;
         size_t_size = wb.getOffsetForName("size_t_size");
-        space_info_size  = wb.getOffsetForName("space_info_size");
+        CDSFileMapRegion_size  = wb.getOffsetForName("CDSFileMapRegion_size");
     }
 
     public static int getFileHeaderSize(FileChannel fc) throws Exception {
@@ -166,7 +166,7 @@
         System.out.printf("%-12s%-12s%-12s%-12s%-12s\n", "Space Name", "Offset", "Used bytes", "Reg Start", "Random Offset");
         start0 = getFileHeaderSize(fc);
         for (int i = 0; i < num_regions; i++) {
-            used_offset = sp_offset + space_info_size * i + sp_used_offset;
+            used_offset = sp_offset + CDSFileMapRegion_size * i + sp_used_offset;
             // read 'used'
             used[i] = readInt(fc, used_offset, size_t_size);
             start = start0;
@@ -199,7 +199,7 @@
         long[] used = new long[num_regions];
         System.out.printf("%-12s%-12s\n", "Space name", "Used bytes");
         for (int i = 0; i < num_regions; i++) {
-            used_offset = sp_offset + space_info_size* i + sp_used_offset;
+            used_offset = sp_offset + CDSFileMapRegion_size* i + sp_used_offset;
             // read 'used'
             used[i] = readInt(fc, used_offset, size_t_size);
             System.out.printf("%-12s%-12d\n", shared_region_name[i], used[i]);