< prev index next >
src/hotspot/share/memory/metaspaceShared.cpp
Print this page
*** 83,92 ****
--- 83,93 ----
bool MetaspaceShared::_remapped_readwrite = false;
address MetaspaceShared::_i2i_entry_code_buffers = NULL;
size_t MetaspaceShared::_i2i_entry_code_buffers_size = 0;
void* MetaspaceShared::_shared_metaspace_static_top = NULL;
intx MetaspaceShared::_relocation_delta;
+ char* MetaspaceShared::_default_base_address;
// The CDS archive is divided into the following regions:
// mc - misc code (the method entry trampolines, c++ vtables)
// rw - read-write metadata
// ro - read-only metadata and read-only tables
*** 242,252 ****
}
void MetaspaceShared::initialize_dumptime_shared_and_meta_spaces() {
assert(DumpSharedSpaces, "should be called for dump time only");
const size_t reserve_alignment = reserved_space_alignment();
- char* shared_base = (char*)align_up((char*)SharedBaseAddress, reserve_alignment);
#ifdef _LP64
// On 64-bit VM, the heap and class space layout will be the same as if
// you're running in -Xshare:on mode:
//
--- 243,252 ----
*** 262,271 ****
--- 262,283 ----
#else
// We don't support archives larger than 256MB on 32-bit due to limited virtual address space.
size_t cds_total = align_down(256*M, reserve_alignment);
#endif
+ char* shared_base = (char*)align_up((char*)SharedBaseAddress, reserve_alignment);
+ if ((shared_base == NULL && SharedBaseAddress != 0) // align_up has wrapped around
+ || (max_uintx - uintx(shared_base) < uintx(cds_total))) { // end of the archive will wrap around
+ log_warning(cds)("SharedBaseAddress (" INTPTR_FORMAT ") is too high. Reverted to " INTPTR_FORMAT,
+ p2i((void*)SharedBaseAddress),
+ p2i((void*)Arguments::default_SharedBaseAddress()));
+ SharedBaseAddress = Arguments::default_SharedBaseAddress();
+ shared_base = (char*)align_up((char*)SharedBaseAddress, reserve_alignment);
+ assert(uintx(shared_base + cds_total) > uintx(shared_base), "must not wrap around");
+ }
+ _default_base_address = shared_base;
+
bool use_requested_base = true;
if (ArchiveRelocationMode == 1) {
log_info(cds)("ArchiveRelocationMode == 1: always allocate class space at an alternative address");
use_requested_base = false;
}
*** 318,327 ****
--- 330,343 ----
init_shared_dump_space(&_mc_region);
SharedBaseAddress = (size_t)_shared_rs.base();
log_info(cds)("Allocated shared space: " SIZE_FORMAT " bytes at " PTR_FORMAT,
_shared_rs.size(), p2i(_shared_rs.base()));
+
+ // We don't want any valid object to be at the very of the archive.
+ // See ArchivePtrMarker::mark_pointer().
+ MetaspaceShared::misc_code_space_alloc(16);
}
// Called by universe_post_init()
void MetaspaceShared::post_initialize(TRAPS) {
if (UseSharedSpaces) {
*** 1454,1470 ****
void VM_PopulateDumpSharedSpace::relocate_to_default_base_address(CHeapBitMap* ptrmap) {
intx addr_delta = MetaspaceShared::final_delta();
if (addr_delta == 0) {
ArchivePtrMarker::compact((address)SharedBaseAddress, (address)_ro_region.top());
} else {
! // We are not able to reserve space at Arguments::default_SharedBaseAddress() (due to ASLR).
// This means that the current content of the archive is based on a random
// address. Let's relocate all the pointers, so that it can be mapped to
! // Arguments::default_SharedBaseAddress() without runtime relocation.
//
// Note: both the base and dynamic archive are written with
! // FileMapHeader::_shared_base_address == Arguments::default_SharedBaseAddress()
// Patch all pointers that are marked by ptrmap within this region,
// where we have just dumped all the metaspace data.
address patch_base = (address)SharedBaseAddress;
address patch_end = (address)_ro_region.top();
--- 1470,1486 ----
void VM_PopulateDumpSharedSpace::relocate_to_default_base_address(CHeapBitMap* ptrmap) {
intx addr_delta = MetaspaceShared::final_delta();
if (addr_delta == 0) {
ArchivePtrMarker::compact((address)SharedBaseAddress, (address)_ro_region.top());
} else {
! // We are not able to reserve space at MetaspaceShared::default_base_address() (due to ASLR).
// This means that the current content of the archive is based on a random
// address. Let's relocate all the pointers, so that it can be mapped to
! // MetaspaceShared::default_base_address() without runtime relocation.
//
// Note: both the base and dynamic archive are written with
! // FileMapHeader::_shared_base_address == MetaspaceShared::default_base_address()
// Patch all pointers that are marked by ptrmap within this region,
// where we have just dumped all the metaspace data.
address patch_base = (address)SharedBaseAddress;
address patch_end = (address)_ro_region.top();
*** 1475,1485 ****
address valid_old_base = patch_base;
address valid_old_end = patch_end;
// after patching, the pointers must point inside this range
// (the requested location of the archive, as mapped at runtime).
! address valid_new_base = (address)Arguments::default_SharedBaseAddress();
address valid_new_end = valid_new_base + size;
log_debug(cds)("Relocating archive from [" INTPTR_FORMAT " - " INTPTR_FORMAT " ] to "
"[" INTPTR_FORMAT " - " INTPTR_FORMAT " ]", p2i(patch_base), p2i(patch_end),
p2i(valid_new_base), p2i(valid_new_end));
--- 1491,1501 ----
address valid_old_base = patch_base;
address valid_old_end = patch_end;
// after patching, the pointers must point inside this range
// (the requested location of the archive, as mapped at runtime).
! address valid_new_base = (address)MetaspaceShared::default_base_address();
address valid_new_end = valid_new_base + size;
log_debug(cds)("Relocating archive from [" INTPTR_FORMAT " - " INTPTR_FORMAT " ] to "
"[" INTPTR_FORMAT " - " INTPTR_FORMAT " ]", p2i(patch_base), p2i(patch_end),
p2i(valid_new_base), p2i(valid_new_end));
*** 1559,1569 ****
// The vtable clones contain addresses of the current process.
// We don't want to write these addresses into the archive.
MetaspaceShared::zero_cpp_vtable_clones_for_writing();
! // relocate the data so that it can be mapped to Arguments::default_SharedBaseAddress()
// without runtime relocation.
relocate_to_default_base_address(&ptrmap);
// Create and write the archive file that maps the shared spaces.
--- 1575,1585 ----
// The vtable clones contain addresses of the current process.
// We don't want to write these addresses into the archive.
MetaspaceShared::zero_cpp_vtable_clones_for_writing();
! // relocate the data so that it can be mapped to MetaspaceShared::default_base_address()
// without runtime relocation.
relocate_to_default_base_address(&ptrmap);
// Create and write the archive file that maps the shared spaces.
*** 1584,1594 ****
_open_archive_heap_regions,
_open_archive_heap_oopmaps,
MetaspaceShared::first_open_archive_heap_region,
MetaspaceShared::max_open_archive_heap_region);
! mapinfo->set_final_requested_base((char*)Arguments::default_SharedBaseAddress());
mapinfo->set_header_crc(mapinfo->compute_header_crc());
mapinfo->write_header();
print_region_stats(mapinfo);
mapinfo->close();
--- 1600,1610 ----
_open_archive_heap_regions,
_open_archive_heap_oopmaps,
MetaspaceShared::first_open_archive_heap_region,
MetaspaceShared::max_open_archive_heap_region);
! mapinfo->set_final_requested_base((char*)MetaspaceShared::default_base_address());
mapinfo->set_header_crc(mapinfo->compute_header_crc());
mapinfo->write_header();
print_region_stats(mapinfo);
mapinfo->close();
*** 2039,2048 ****
--- 2055,2065 ----
if (dynamic_mapped) {
FileMapInfo::set_shared_path_table(dynamic_mapinfo);
} else {
FileMapInfo::set_shared_path_table(static_mapinfo);
}
+ _default_base_address = static_mapinfo->requested_base_address();
} else {
set_shared_metaspace_range(NULL, NULL, NULL);
UseSharedSpaces = false;
FileMapInfo::fail_continue("Unable to map shared spaces");
if (PrintSharedArchiveAndExit) {
*** 2086,2095 ****
--- 2103,2117 ----
// use_requested_addr:
// true = map at FileMapHeader::_requested_base_address
// false = map at an alternative address picked by OS.
MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, FileMapInfo* dynamic_mapinfo,
bool use_requested_addr) {
+ if (use_requested_addr && static_mapinfo->requested_base_address() == NULL) {
+ log_info(cds)("Archive(s) were created with -XX:SharedBaseAddress=0. Always map at os-selected address");
+ return MAP_ARCHIVE_MMAP_FAILURE;
+ }
+
PRODUCT_ONLY(if (ArchiveRelocationMode == 1 && use_requested_addr) {
// For product build only -- this is for benchmarking the cost of doing relocation.
// For debug builds, the check is done in FileMapInfo::map_regions for better test coverage.
log_info(cds)("ArchiveRelocationMode == 1: always map archive(s) at an alternative address");
return MAP_ARCHIVE_MMAP_FAILURE;
*** 2409,2419 ****
vm_exit_during_initialization(err_msg("Unable to allocate from '%s' region", name),
"Please reduce the number of shared classes.");
}
! // This is used to relocate the pointers so that the archive can be mapped at
! // Arguments::default_SharedBaseAddress() without runtime relocation.
intx MetaspaceShared::final_delta() {
! return intx(Arguments::default_SharedBaseAddress()) // We want the archive to be mapped to here at runtime
! - intx(SharedBaseAddress); // .. but the archive is mapped at here at dump time
}
--- 2431,2441 ----
vm_exit_during_initialization(err_msg("Unable to allocate from '%s' region", name),
"Please reduce the number of shared classes.");
}
! // This is used to relocate the pointers so that the base archive can be mapped at
! // MetaspaceShared::default_base_address() without runtime relocation.
intx MetaspaceShared::final_delta() {
! return intx(MetaspaceShared::default_base_address()) // We want the base archive to be mapped to here at runtime
! - intx(SharedBaseAddress); // .. but the base archive is mapped at here at dump time
}
< prev index next >