# HG changeset patch # User jiangli # Date 1507332807 14400 # Node ID 0fb1d501c408aed10f3d665ebcf51f26098ce0ec # Parent 92aab488afdcb75a56eaae2de38e219376a6d57e 8174986: CDS archived java heap region may not compatible with AOT Summary: Always uses LogKlassAlignmentInBytes for narrow_klass_shift when CDS is enabled. Reviewed-by: iklam, ccheung diff -r 92aab488afdc -r 0fb1d501c408 src/hotspot/share/memory/filemap.cpp --- a/src/hotspot/share/memory/filemap.cpp Fri Oct 06 13:00:18 2017 -0700 +++ b/src/hotspot/share/memory/filemap.cpp Fri Oct 06 19:33:27 2017 -0400 @@ -182,6 +182,7 @@ _obj_alignment = ObjectAlignmentInBytes; _compact_strings = CompactStrings; _narrow_oop_mode = Universe::narrow_oop_mode(); + _narrow_oop_base = Universe::narrow_oop_base(); _narrow_oop_shift = Universe::narrow_oop_shift(); _max_heap_size = MaxHeapSize; _narrow_klass_base = Universe::narrow_klass_base(); @@ -687,8 +688,14 @@ // open archive objects. void FileMapInfo::map_heap_regions() { if (MetaspaceShared::is_heap_object_archiving_allowed()) { + log_info(cds)("Archived narrow_oop_mode = %d, narrow_oop_base = " PTR_FORMAT ", narrow_oop_shift = %d", + narrow_oop_mode(), p2i(narrow_oop_base()), narrow_oop_shift()); + log_info(cds)("Archived narrow_klass_base = " PTR_FORMAT ", narrow_klass_shift = %d", + p2i(narrow_klass_base()), narrow_klass_shift()); + // Check that all the narrow oop and klass encodings match the archive if (narrow_oop_mode() != Universe::narrow_oop_mode() || + narrow_oop_base() != Universe::narrow_oop_base() || narrow_oop_shift() != Universe::narrow_oop_shift() || narrow_klass_base() != Universe::narrow_klass_base() || narrow_klass_shift() != Universe::narrow_klass_shift()) { @@ -697,6 +704,11 @@ "The current CompressedOops/CompressedClassPointers encoding differs from " "that archived due to heap size change. The archive was dumped using max heap " "size " UINTX_FORMAT "M.", max_heap_size()/M); + log_info(cds)("Current narrow_oop_mode = %d, narrow_oop_base = " PTR_FORMAT ", narrow_oop_shift = %d", + Universe::narrow_oop_mode(), p2i(Universe::narrow_oop_base()), + Universe::narrow_oop_shift()); + log_info(cds)("Current narrow_klass_base = " PTR_FORMAT ", narrow_klass_shift = %d", + p2i(Universe::narrow_klass_base()), Universe::narrow_klass_shift()); } } else { // First, map string regions as closed archive heap regions. diff -r 92aab488afdc -r 0fb1d501c408 src/hotspot/share/memory/filemap.hpp --- a/src/hotspot/share/memory/filemap.hpp Fri Oct 06 13:00:18 2017 -0700 +++ b/src/hotspot/share/memory/filemap.hpp Fri Oct 06 19:33:27 2017 -0400 @@ -112,6 +112,7 @@ 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 @@ -203,12 +204,13 @@ int version() { return _header->_version; } size_t alignment() { return _header->_alignment; } 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; } + 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; } + 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; } diff -r 92aab488afdc -r 0fb1d501c408 src/hotspot/share/memory/metaspace.cpp --- a/src/hotspot/share/memory/metaspace.cpp Fri Oct 06 13:00:18 2017 -0700 +++ b/src/hotspot/share/memory/metaspace.cpp Fri Oct 06 19:33:27 2017 -0400 @@ -3103,10 +3103,16 @@ Universe::set_narrow_klass_base(lower_base); - if ((uint64_t)(higher_address - lower_base) <= UnscaledClassSpaceMax) { + // CDS uses LogKlassAlignmentInBytes for narrow_klass_shift. See + // MetaspaceShared::initialize_dumptime_shared_and_meta_spaces() for + // how dump time narrow_klass_shift is set. Although, CDS can work + // with zero-shift mode also, to be consistent with AOT it uses + // LogKlassAlignmentInBytes for klass shift so archived java heap objects + // can be used at same time as AOT code. + if (!UseSharedSpaces + && (uint64_t)(higher_address - lower_base) <= UnscaledClassSpaceMax) { Universe::set_narrow_klass_shift(0); } else { - assert(!UseSharedSpaces, "Cannot shift with UseSharedSpaces"); Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes); } AOTLoader::set_narrow_klass_shift(); @@ -3325,50 +3331,25 @@ #if INCLUDE_CDS if (DumpSharedSpaces) { - MetaspaceShared::initialize_shared_rs(); + MetaspaceShared::initialize_dumptime_shared_and_meta_spaces(); } else if (UseSharedSpaces) { - // 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; - FileMapInfo* mapinfo = new FileMapInfo(); - - // Open the shared archive file, read and validate the header. If - // initialization fails, shared spaces [UseSharedSpaces] are - // disabled and the file is closed. - // Map in spaces now also - if (mapinfo->initialize() && MetaspaceShared::map_shared_spaces(mapinfo)) { - size_t cds_total = MetaspaceShared::core_spaces_size(); - cds_address = (address)mapinfo->header()->region_addr(0); + // If any of the archived space fails to map, UseSharedSpaces + // is reset to false. Fall through to the + // (!DumpSharedSpaces && !UseSharedSpaces) case to set up class + // metaspace. + MetaspaceShared::initialize_runtime_shared_and_meta_spaces(); + } + + if (!DumpSharedSpaces && !UseSharedSpaces) +#endif // INCLUDE_CDS + { #ifdef _LP64 - if (using_class_space()) { - char* cds_end = (char*)(cds_address + cds_total); - cds_end = (char *)align_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_heap_regions() compares the current narrow oop and klass encodings - // with the archived ones, so it must be done after all encodings are determined. - mapinfo->map_heap_regions(); - } -#endif // _LP64 - } else { - assert(!mapinfo->is_open() && !UseSharedSpaces, - "archive file not closed or shared spaces not disabled."); - } - } -#endif // INCLUDE_CDS - -#ifdef _LP64 - if (!UseSharedSpaces && using_class_space()) { - if (DumpSharedSpaces) { - // Already initialized inside MetaspaceShared::initialize_shared_rs() - } else { + if (using_class_space()) { char* base = (char*)align_up(Universe::heap()->reserved_region().end(), _reserve_alignment); allocate_metaspace_compressed_klass_ptrs(base, 0); } +#endif // _LP64 } -#endif // _LP64 // Initialize these before initializing the VirtualSpaceList _first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord; diff -r 92aab488afdc -r 0fb1d501c408 src/hotspot/share/memory/metaspace.hpp --- a/src/hotspot/share/memory/metaspace.hpp Fri Oct 06 13:00:18 2017 -0700 +++ b/src/hotspot/share/memory/metaspace.hpp Fri Oct 06 19:33:27 2017 -0400 @@ -179,6 +179,10 @@ assert(DumpSharedSpaces, "sanity"); DEBUG_ONLY(_frozen = true;) } +#ifdef _LP64 + static void allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base); +#endif + private: #ifdef _LP64 @@ -187,8 +191,6 @@ // Returns true if can use CDS with metaspace allocated as specified address. static bool can_use_cds_with_metaspace_addr(char* metaspace_base, address cds_base); - static void allocate_metaspace_compressed_klass_ptrs(char* requested_addr, address cds_base); - static void initialize_class_space(ReservedSpace rs); #endif size_t class_chunk_size(size_t word_size); diff -r 92aab488afdc -r 0fb1d501c408 src/hotspot/share/memory/metaspaceShared.cpp --- a/src/hotspot/share/memory/metaspaceShared.cpp Fri Oct 06 13:00:18 2017 -0700 +++ b/src/hotspot/share/memory/metaspaceShared.cpp Fri Oct 06 19:33:27 2017 -0400 @@ -214,7 +214,42 @@ return _ro_region.allocate(num_bytes); } -void MetaspaceShared::initialize_shared_rs() { +void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { + assert(UseSharedSpaces, "Must be called when UseSharedSpaces is enabled"); + + // 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; + FileMapInfo* mapinfo = new FileMapInfo(); + + // Open the shared archive file, read and validate the header. If + // initialization fails, shared spaces [UseSharedSpaces] are + // disabled and the file is closed. + // Map in spaces now also + if (mapinfo->initialize() && map_shared_spaces(mapinfo)) { + size_t cds_total = core_spaces_size(); + cds_address = (address)mapinfo->header()->region_addr(0); +#ifdef _LP64 + if (Metaspace::using_class_space()) { + char* cds_end = (char*)(cds_address + cds_total); + cds_end = (char *)align_up(cds_end, Metaspace::reserve_alignment()); + // If UseCompressedClassPointers is set then allocate the metaspace area + // above the heap and above the CDS area (if it exists). + Metaspace::allocate_metaspace_compressed_klass_ptrs(cds_end, cds_address); + // map_heap_regions() compares the current narrow oop and klass encodings + // with the archived ones, so it must be done after all encodings are determined. + mapinfo->map_heap_regions(); + } +#endif // _LP64 + } else { + assert(!mapinfo->is_open() && !UseSharedSpaces, + "archive file not closed or shared spaces not disabled."); + } +} + +void MetaspaceShared::initialize_dumptime_shared_and_meta_spaces() { + assert(DumpSharedSpaces, "should be called for dump time only"); const size_t reserve_alignment = Metaspace::reserve_alignment(); bool large_pages = false; // No large pages when dumping the CDS archive. char* shared_base = (char*)align_up((char*)SharedBaseAddress, reserve_alignment); @@ -223,12 +258,12 @@ // On 64-bit VM, the heap and class space layout will be the same as if // you're running in -Xshare:on mode: // - // +-- SharedBaseAddress (default = 0x800000000) - // v - // +-..---------+----+ ... +----+----+----+----+----+---------------+ - // | Heap | ST | | MC | RW | RO | MD | OD | class space | - // +-..---------+----+ ... +----+----+----+----+----+---------------+ - // |<--MaxHeapSize->| |<-- UnscaledClassSpaceMax = 4GB ------->| + // +-- SharedBaseAddress (default = 0x800000000) + // v + // +-..---------+---------+ ... +----+----+----+----+----+---------------+ + // | Heap | Archive | | MC | RW | RO | MD | OD | class space | + // +-..---------+---------+ ... +----+----+----+----+----+---------------+ + // |<-- MaxHeapSize -->| |<-- UnscaledClassSpaceMax = 4GB ------->| // const uint64_t UnscaledClassSpaceMax = (uint64_t(max_juint) + 1); const size_t cds_total = align_down(UnscaledClassSpaceMax, reserve_alignment); @@ -268,12 +303,9 @@ // Set up compress class pointers. Universe::set_narrow_klass_base((address)_shared_rs.base()); - if (UseAOT || cds_total > UnscaledClassSpaceMax) { - // AOT forces narrow_klass_shift=LogKlassAlignmentInBytes - Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes); - } else { - Universe::set_narrow_klass_shift(0); - } + // Set narrow_klass_shift to be LogKlassAlignmentInBytes. This is consistent + // with AOT. + Universe::set_narrow_klass_shift(LogKlassAlignmentInBytes); Metaspace::initialize_class_space(tmp_class_space); tty->print_cr("narrow_klass_base = " PTR_FORMAT ", narrow_klass_shift = %d", diff -r 92aab488afdc -r 0fb1d501c408 src/hotspot/share/memory/metaspaceShared.hpp --- a/src/hotspot/share/memory/metaspaceShared.hpp Fri Oct 06 13:00:18 2017 -0700 +++ b/src/hotspot/share/memory/metaspaceShared.hpp Fri Oct 06 19:33:27 2017 -0400 @@ -146,7 +146,8 @@ static size_t core_spaces_size() { return _core_spaces_size; } - static void initialize_shared_rs() NOT_CDS_RETURN; + static void initialize_dumptime_shared_and_meta_spaces() NOT_CDS_RETURN; + static void initialize_runtime_shared_and_meta_spaces() NOT_CDS_RETURN; // Delta of this object from the bottom of the archive. static uintx object_delta(void* obj) {