# HG changeset patch # User coleenp # Date 1434577488 0 # Node ID 8957ccbb582113e97d77522a0d898bf709b9856a # Parent a6ab7217b5cc1034d64661d293b408365f3a20bd 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 diff -r a6ab7217b5cc -r 8957ccbb5821 hotspot/src/share/vm/memory/filemap.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) { diff -r a6ab7217b5cc -r 8957ccbb5821 hotspot/src/share/vm/memory/filemap.hpp --- 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; } diff -r a6ab7217b5cc -r 8957ccbb5821 hotspot/src/share/vm/memory/metaspace.cpp --- 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 diff -r a6ab7217b5cc -r 8957ccbb5821 hotspot/src/share/vm/memory/metaspaceShared.cpp --- 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(); diff -r a6ab7217b5cc -r 8957ccbb5821 hotspot/src/share/vm/prims/whitebox.cpp --- 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