8098821: Crash in system dictionary initialization with shared strings
authorcoleenp
Wed, 17 Jun 2015 21:44:48 +0000
changeset 31362 8957ccbb5821
parent 31352 a6ab7217b5cc
child 31363 9c6744fc266e
child 31371 311143309e73
8098821: Crash in system dictionary initialization with shared strings Summary: map string regions after the compressed class base is known Reviewed-by: iklam, dcubed Contributed-by: coleen.phillimore@oracle.com, mikhailo.seledtsov@oracle.com
hotspot/src/share/vm/memory/filemap.cpp
hotspot/src/share/vm/memory/filemap.hpp
hotspot/src/share/vm/memory/metaspace.cpp
hotspot/src/share/vm/memory/metaspaceShared.cpp
hotspot/src/share/vm/prims/whitebox.cpp
--- a/hotspot/src/share/vm/memory/filemap.cpp	Tue Jun 16 11:58:25 2015 +0200
+++ b/hotspot/src/share/vm/memory/filemap.cpp	Wed Jun 17 21:44:48 2015 +0000
@@ -172,6 +172,8 @@
   _narrow_oop_mode = Universe::narrow_oop_mode();
   _narrow_oop_shift = Universe::narrow_oop_shift();
   _max_heap_size = MaxHeapSize;
+  _narrow_klass_base = Universe::narrow_klass_base();
+  _narrow_klass_shift = Universe::narrow_klass_shift();
   _classpath_entry_table_size = mapinfo->_classpath_entry_table_size;
   _classpath_entry_table = mapinfo->_classpath_entry_table;
   _classpath_entry_size = mapinfo->_classpath_entry_size;
@@ -652,8 +654,18 @@
 bool FileMapInfo::map_string_regions() {
 #if INCLUDE_ALL_GCS
   if (UseG1GC && UseCompressedOops && UseCompressedClassPointers) {
-    if (narrow_oop_mode() == Universe::narrow_oop_mode() &&
-        narrow_oop_shift() == Universe::narrow_oop_shift()) {
+    // Check that all the narrow oop and klass encodings match the archive
+    if (narrow_oop_mode() != Universe::narrow_oop_mode() ||
+        narrow_oop_shift() != Universe::narrow_oop_shift() ||
+        narrow_klass_base() != Universe::narrow_klass_base() ||
+        narrow_klass_shift() != Universe::narrow_klass_shift()) {
+      if (PrintSharedSpaces && _header->_space[MetaspaceShared::first_string]._used > 0) {
+        tty->print_cr("Shared string 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 "
+                     "size %dM.", max_heap_size()/M);
+      }
+    } else {
       string_ranges = new MemRegion[MetaspaceShared::max_strings];
       struct FileMapInfo::FileMapHeader::space_info* si;
 
@@ -671,6 +683,7 @@
       }
 
       if (num_ranges == 0) {
+        StringTable::ignore_shared_strings(true);
         return true; // no shared string data
       }
 
@@ -702,15 +715,14 @@
           return false;
         }
       }
-      return true; // the shared string data is mapped successfuly
-    } else {
-      //  narrow oop encoding differ, the shared string data are not used
-      if (PrintSharedSpaces && _header->_space[MetaspaceShared::first_string]._used > 0) {
-        tty->print_cr("Shared string data from the CDS archive is being ignored. "
-                     "The current CompressedOops encoding differs from that archived "
-                     "due to heap size change. The archive was dumped using max heap "
-                     "size %dM.", max_heap_size() >> 20);
+
+      if (!verify_string_regions()) {
+        fail_continue("Shared string regions are corrupt");
+        return false;
       }
+
+      // the shared string data is mapped successfully
+      return true;
     }
   } else {
     if (PrintSharedSpaces && _header->_space[MetaspaceShared::first_string]._used > 0) {
--- a/hotspot/src/share/vm/memory/filemap.hpp	Tue Jun 16 11:58:25 2015 +0200
+++ b/hotspot/src/share/vm/memory/filemap.hpp	Wed Jun 17 21:44:48 2015 +0000
@@ -97,6 +97,8 @@
     int    _narrow_oop_shift;         // compressed oop encoding shift
     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;
 
     struct space_info {
       int    _crc;           // crc checksum of the current space
@@ -178,6 +180,8 @@
   Universe::NARROW_OOP_MODE narrow_oop_mode() { return _header->_narrow_oop_mode; }
   int    narrow_oop_shift()           { return _header->_narrow_oop_shift; }
   uintx  max_heap_size()              { 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; }
   size_t space_capacity(int i)        { return _header->_space[i]._capacity; }
   struct FileMapHeader* header()      { return _header; }
 
--- a/hotspot/src/share/vm/memory/metaspace.cpp	Tue Jun 16 11:58:25 2015 +0200
+++ b/hotspot/src/share/vm/memory/metaspace.cpp	Wed Jun 17 21:44:48 2015 +0000
@@ -3293,12 +3293,12 @@
 #endif // _LP64
 #endif // INCLUDE_CDS
   } else {
-#if INCLUDE_CDS
     // If using shared space, open the file that contains the shared space
     // and map in the memory before initializing the rest of metaspace (so
     // the addresses don't conflict)
     address cds_address = NULL;
     if (UseSharedSpaces) {
+#if INCLUDE_CDS
       FileMapInfo* mapinfo = new FileMapInfo();
 
       // Open the shared archive file, read and validate the header. If
@@ -3308,26 +3308,29 @@
       if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) {
         cds_total = FileMapInfo::shared_spaces_size();
         cds_address = (address)mapinfo->header()->region_addr(0);
+#ifdef _LP64
+        if (using_class_space()) {
+          char* cds_end = (char*)(cds_address + cds_total);
+          cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
+          // If UseCompressedClassPointers is set then allocate the metaspace area
+          // above the heap and above the CDS area (if it exists).
+          allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
+          // Map the shared string space after compressed pointers
+          // because it relies on compressed class pointers setting to work
+          mapinfo->map_string_regions();
+        }
+#endif // _LP64
       } else {
         assert(!mapinfo->is_open() && !UseSharedSpaces,
                "archive file not closed or shared spaces not disabled.");
       }
+#endif // INCLUDE_CDS
     }
-#endif // INCLUDE_CDS
+
 #ifdef _LP64
-    // If UseCompressedClassPointers is set then allocate the metaspace area
-    // above the heap and above the CDS area (if it exists).
-    if (using_class_space()) {
-      if (UseSharedSpaces) {
-#if INCLUDE_CDS
-        char* cds_end = (char*)(cds_address + cds_total);
-        cds_end = (char *)align_ptr_up(cds_end, _reserve_alignment);
-        allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address);
-#endif
-      } else {
-        char* base = (char*)align_ptr_up(Universe::heap()->reserved_region().end(), _reserve_alignment);
-        allocate_metaspace_compressed_klass_ptrs(base, 0);
-      }
+    if (!UseSharedSpaces && using_class_space()) {
+      char* base = (char*)align_ptr_up(Universe::heap()->reserved_region().end(), _reserve_alignment);
+      allocate_metaspace_compressed_klass_ptrs(base, 0);
     }
 #endif // _LP64
 
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp	Tue Jun 16 11:58:25 2015 +0200
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp	Wed Jun 17 21:44:48 2015 +0000
@@ -1001,8 +1001,6 @@
       mapinfo->verify_region_checksum(md) &&
       (_mc_base = mapinfo->map_region(mc)) != NULL &&
       mapinfo->verify_region_checksum(mc) &&
-      mapinfo->map_string_regions() &&
-      mapinfo->verify_string_regions() &&
       (image_alignment == (size_t)max_alignment()) &&
       mapinfo->validate_classpath_entry_table()) {
     // Success (no need to do anything)
@@ -1014,7 +1012,6 @@
     if (_rw_base != NULL) mapinfo->unmap_region(rw);
     if (_md_base != NULL) mapinfo->unmap_region(md);
     if (_mc_base != NULL) mapinfo->unmap_region(mc);
-    mapinfo->unmap_string_regions();
 #ifndef _WINDOWS
     // Release the entire mapped region
     shared_rs.release();
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Tue Jun 16 11:58:25 2015 +0200
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Wed Jun 17 21:44:48 2015 +0000
@@ -1213,6 +1213,10 @@
   return MetaspaceShared::is_in_shared_space((void*)obj_oop);
 WB_END
 
+WB_ENTRY(jboolean, WB_AreSharedStringsIgnored(JNIEnv* env))
+  return StringTable::shared_string_ignored();
+WB_END
+
 //Some convenience methods to deal with objects from java
 int WhiteBox::offset_for_field(const char* field_name, oop object,
     Symbol* signature_symbol) {
@@ -1438,6 +1442,7 @@
       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/String;",
                                                       (void*)&WB_GetMethodStringOption},
   {CC"isShared",           CC"(Ljava/lang/Object;)Z", (void*)&WB_IsShared },
+  {CC"areSharedStringsIgnored",           CC"()Z",    (void*)&WB_AreSharedStringsIgnored },
 };
 
 #undef CC