mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-03 20:50:19 +00:00
8174986: CDS archived java heap region may not compatible with AOT
Always uses LogKlassAlignmentInBytes for narrow_klass_shift when CDS is enabled. Reviewed-by: iklam, ccheung
This commit is contained in:
parent
e24a5bc2ff
commit
3ccd60110d
@ -182,6 +182,7 @@ void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment
|
||||
_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 @@ static int num_open_archive_heap_ranges = 0;
|
||||
// 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 @@ void FileMapInfo::map_heap_regions() {
|
||||
"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.
|
||||
|
||||
@ -112,6 +112,7 @@ public:
|
||||
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 @@ public:
|
||||
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; }
|
||||
|
||||
@ -3103,10 +3103,16 @@ void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address
|
||||
|
||||
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 @@ void Metaspace::global_initialize() {
|
||||
|
||||
#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);
|
||||
#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.");
|
||||
}
|
||||
// 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();
|
||||
}
|
||||
#endif // INCLUDE_CDS
|
||||
|
||||
if (!DumpSharedSpaces && !UseSharedSpaces)
|
||||
#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
|
||||
}
|
||||
|
||||
// Initialize these before initializing the VirtualSpaceList
|
||||
_first_chunk_word_size = InitialBootClassLoaderMetaspaceSize / BytesPerWord;
|
||||
|
||||
@ -179,6 +179,10 @@ class Metaspace : public CHeapObj<mtClass> {
|
||||
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 @@ class Metaspace : public CHeapObj<mtClass> {
|
||||
// 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);
|
||||
|
||||
@ -214,7 +214,42 @@ char* MetaspaceShared::read_only_space_alloc(size_t num_bytes) {
|
||||
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 @@ void MetaspaceShared::initialize_shared_rs() {
|
||||
// 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 @@ void MetaspaceShared::initialize_shared_rs() {
|
||||
|
||||
// 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",
|
||||
|
||||
@ -146,7 +146,8 @@ class MetaspaceShared : AllStatic {
|
||||
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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user