< 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 >