< prev index next >
src/hotspot/share/memory/filemap.cpp
Print this page
*** 33,58 ****
--- 33,62 ----
#include "classfile/altHashing.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "logging/logMessage.hpp"
#include "memory/filemap.hpp"
+ #include "memory/heapShared.inline.hpp"
+ #include "memory/iterator.inline.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/metaspaceClosure.hpp"
#include "memory/metaspaceShared.hpp"
#include "memory/oopFactory.hpp"
#include "oops/compressedOops.inline.hpp"
#include "oops/objArrayOop.hpp"
+ #include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/arguments.hpp"
#include "runtime/java.hpp"
#include "runtime/os.inline.hpp"
#include "runtime/vm_version.hpp"
#include "services/memTracker.hpp"
#include "utilities/align.hpp"
#include "utilities/defaultStream.hpp"
#if INCLUDE_G1GC
#include "gc/g1/g1CollectedHeap.hpp"
+ #include "gc/g1/heapRegion.hpp"
#endif
# include <sys/stat.h>
# include <errno.h>
*** 186,195 ****
--- 190,202 ----
_narrow_klass_base = Universe::narrow_klass_base();
_narrow_klass_shift = Universe::narrow_klass_shift();
_shared_path_table_size = mapinfo->_shared_path_table_size;
_shared_path_table = mapinfo->_shared_path_table;
_shared_path_entry_size = mapinfo->_shared_path_entry_size;
+ if (MetaspaceShared::is_heap_object_archiving_allowed()) {
+ _heap_reserved = Universe::heap()->reserved_region();
+ }
// The following fields are for sanity checks for whether this archive
// will function correctly with this JVM and the bootclasspath it's
// invoked with.
*** 651,667 ****
//
// "X" represented space that's occupied by heap objects.
// "_" represented unused spaced in the heap region.
//
//
! // |ah0 | ah1 | ah2| ...... | ahn |
// |XXXXXX|__ |XXXXX|XXXX|XXXXXXXX|XXXX|
// |<-r0->| |<- r1 ----------------->|
// ^^^
// |
// +-- gap
size_t FileMapInfo::write_archive_heap_regions(GrowableArray<MemRegion> *heap_mem,
int first_region_id, int max_num_regions) {
assert(max_num_regions <= 2, "Only support maximum 2 memory regions");
int arr_len = heap_mem == NULL ? 0 : heap_mem->length();
if(arr_len > max_num_regions) {
--- 658,675 ----
//
// "X" represented space that's occupied by heap objects.
// "_" represented unused spaced in the heap region.
//
//
! // |ah0 | ah1 | ah2| ...... | ahn|
// |XXXXXX|__ |XXXXX|XXXX|XXXXXXXX|XXXX|
// |<-r0->| |<- r1 ----------------->|
// ^^^
// |
// +-- gap
size_t FileMapInfo::write_archive_heap_regions(GrowableArray<MemRegion> *heap_mem,
+ GrowableArray<ArchiveHeapOopmapInfo> *oopmaps,
int first_region_id, int max_num_regions) {
assert(max_num_regions <= 2, "Only support maximum 2 memory regions");
int arr_len = heap_mem == NULL ? 0 : heap_mem->length();
if(arr_len > max_num_regions) {
*** 682,691 ****
--- 690,703 ----
}
log_info(cds)("Archive heap region %d " INTPTR_FORMAT " - " INTPTR_FORMAT " = " SIZE_FORMAT_W(8) " bytes",
i, p2i(start), p2i(start + size), size);
write_region(i, start, size, false, false);
+ if (size > 0) {
+ space_at(i)->_oopmap = oopmaps->at(arr_idx)._oopmap;
+ space_at(i)->_oopmap_size_in_bits = oopmaps->at(arr_idx)._oopmap_size_in_bits;
+ }
}
return total_size;
}
// Dump bytes to file -- at the current file position.
*** 760,770 ****
size_t used = si->_used;
size_t size = align_up(used, os::vm_allocation_granularity());
if (!open_for_read()) {
return false;
}
! char *addr = _header->region_addr(idx);
char *base = os::remap_memory(_fd, _full_path, si->_file_offset,
addr, size, false /* !read_only */,
si->_allow_exec);
close();
if (base == NULL) {
--- 772,782 ----
size_t used = si->_used;
size_t size = align_up(used, os::vm_allocation_granularity());
if (!open_for_read()) {
return false;
}
! char *addr = region_addr(idx);
char *base = os::remap_memory(_fd, _full_path, si->_file_offset,
addr, size, false /* !read_only */,
si->_allow_exec);
close();
if (base == NULL) {
*** 779,789 ****
return true;
}
// Map the whole region at once, assumed to be allocated contiguously.
ReservedSpace FileMapInfo::reserve_shared_memory() {
! char* requested_addr = _header->region_addr(0);
size_t size = FileMapInfo::core_spaces_size();
// Reserve the space first, then map otherwise map will go right over some
// other reserved memory (like the code cache).
ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr);
--- 791,801 ----
return true;
}
// Map the whole region at once, assumed to be allocated contiguously.
ReservedSpace FileMapInfo::reserve_shared_memory() {
! char* requested_addr = region_addr(0);
size_t size = FileMapInfo::core_spaces_size();
// Reserve the space first, then map otherwise map will go right over some
// other reserved memory (like the code cache).
ReservedSpace rs(size, os::vm_allocation_granularity(), false, requested_addr);
*** 806,816 ****
assert(!MetaspaceShared::is_heap_region(i), "sanity");
CDSFileMapRegion* si = space_at(i);
size_t used = si->_used;
size_t alignment = os::vm_allocation_granularity();
size_t size = align_up(used, alignment);
! char *requested_addr = _header->region_addr(i);
// If a tool agent is in use (debugging enabled), we must map the address space RW
if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) {
si->_read_only = false;
}
--- 818,828 ----
assert(!MetaspaceShared::is_heap_region(i), "sanity");
CDSFileMapRegion* si = space_at(i);
size_t used = si->_used;
size_t alignment = os::vm_allocation_granularity();
size_t size = align_up(used, alignment);
! char *requested_addr = region_addr(i);
// If a tool agent is in use (debugging enabled), we must map the address space RW
if (JvmtiExport::can_modify_any_class() || JvmtiExport::can_walk_any_space()) {
si->_read_only = false;
}
*** 836,890 ****
*top_ret = base + size;
return base;
}
static MemRegion *string_ranges = NULL;
static MemRegion *open_archive_heap_ranges = NULL;
static int num_string_ranges = 0;
static int num_open_archive_heap_ranges = 0;
#if INCLUDE_CDS_JAVA_HEAP
//
// Map the shared string objects and open archive heap objects to the runtime
// java heap.
//
! // The shared strings are mapped near the runtime java heap top. The
! // mapped strings contain no out-going references to any other java heap
! // regions. GC does not write into the mapped shared strings.
//
// The open archive heap objects are mapped below the shared strings in
// the runtime java heap. The mapped open archive heap data only contain
// references to the shared strings and open archive objects initially.
// During runtime execution, out-going references to any other java heap
// regions may be added. GC may mark and update references in the mapped
// 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()) {
! if (log_is_enabled(Info, cds) && space_at(MetaspaceShared::first_string)->_used > 0) {
! log_info(cds)("Cached heap 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 " 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.
// GC does not write into the regions.
if (map_heap_data(&string_ranges,
MetaspaceShared::first_string,
MetaspaceShared::max_strings,
--- 848,995 ----
*top_ret = base + size;
return base;
}
+ address FileMapInfo::decode_start_address(CDSFileMapRegion* spc, bool with_current_oop_encoding_mode) {
+ if (with_current_oop_encoding_mode) {
+ return (address)CompressedOops::decode_not_null(offset_of_space(spc));
+ } else {
+ return (address)HeapShared::decode_with_archived_oop_encoding_mode(offset_of_space(spc));
+ }
+ }
+
static MemRegion *string_ranges = NULL;
static MemRegion *open_archive_heap_ranges = NULL;
static int num_string_ranges = 0;
static int num_open_archive_heap_ranges = 0;
#if INCLUDE_CDS_JAVA_HEAP
+ bool FileMapInfo::has_heap_regions() {
+ return (_header->_space[MetaspaceShared::first_string]._used > 0);
+ }
+
+ // Returns the address range of the archived heap regions computed using the
+ // current oop encoding mode. This range may be different than the one seen at
+ // dump time due to encoding mode differences. The result is used in determining
+ // if/how these regions should be relocated at run time.
+ MemRegion FileMapInfo::get_heap_regions_range_with_current_oop_encoding_mode() {
+ address start = (address) max_uintx;
+ address end = NULL;
+
+ for (int i = MetaspaceShared::first_string; i <= MetaspaceShared::last_valid_region; i++) {
+ CDSFileMapRegion* si = space_at(i);
+ size_t size = si->_used;
+ if (size > 0) {
+ address s = start_address_with_current_oop_encoding_mode(si);
+ address e = s + size;
+ if (start > s) {
+ start = s;
+ }
+ if (end < e) {
+ end = e;
+ }
+ }
+ }
+ assert(end != NULL, "must have at least one used heap region");
+ return MemRegion((HeapWord*)start, (HeapWord*)end);
+ }
+
//
// Map the shared string objects and open archive heap objects to the runtime
// java heap.
//
! // The shared strings are mapped close to the end of the java heap top in
! // closed archive regions. The mapped strings contain no out-going references
! // to any other java heap regions. GC does not write into the mapped shared strings.
//
// The open archive heap objects are mapped below the shared strings in
// the runtime java heap. The mapped open archive heap data only contain
// references to the shared strings and open archive objects initially.
// During runtime execution, out-going references to any other java heap
// regions may be added. GC may mark and update references in the mapped
// open archive objects.
! void FileMapInfo::map_heap_regions_impl() {
! if (!MetaspaceShared::is_heap_object_archiving_allowed()) {
! log_info(cds)("CDS heap data is being ignored. UseG1GC, "
! "UseCompressedOops and UseCompressedClassPointers are required.");
! return;
! }
!
! MemRegion heap_reserved = Universe::heap()->reserved_region();
!
! log_info(cds)("CDS archive was created with max heap size = " SIZE_FORMAT "M, and the following configuration:",
! max_heap_size()/M);
! log_info(cds)(" narrow_klass_base = " PTR_FORMAT ", narrow_klass_shift = %d",
p2i(narrow_klass_base()), narrow_klass_shift());
+ log_info(cds)(" 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)("The current max heap size = " SIZE_FORMAT "M, HeapRegion::GrainBytes = " SIZE_FORMAT,
! heap_reserved.byte_size()/M, HeapRegion::GrainBytes);
! log_info(cds)(" narrow_klass_base = " PTR_FORMAT ", narrow_klass_shift = %d",
p2i(Universe::narrow_klass_base()), Universe::narrow_klass_shift());
+ log_info(cds)(" 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());
+
+ if (narrow_klass_base() != Universe::narrow_klass_base() ||
+ narrow_klass_shift() != Universe::narrow_klass_shift()) {
+ log_info(cds)("CDS heap data cannot be used because the archive was created with an incompatible narrow klass encoding mode.");
+ return;
}
+
+ if (narrow_oop_mode() != Universe::narrow_oop_mode() ||
+ narrow_oop_base() != Universe::narrow_oop_base() ||
+ narrow_oop_shift() != Universe::narrow_oop_shift()) {
+ log_info(cds)("CDS heap data need to be relocated because the archive was created with an incompatible oop encoding mode.");
+ _heap_pointers_need_patching = true;
} else {
+ MemRegion range = get_heap_regions_range_with_current_oop_encoding_mode();
+ if (!heap_reserved.contains(range)) {
+ log_info(cds)("CDS heap data need to be relocated because");
+ log_info(cds)("the desired range " PTR_FORMAT " - " PTR_FORMAT, p2i(range.start()), p2i(range.end()));
+ log_info(cds)("is outside of the heap " PTR_FORMAT " - " PTR_FORMAT, p2i(heap_reserved.start()), p2i(heap_reserved.end()));
+ _heap_pointers_need_patching = true;
+ }
+ }
+
+ ptrdiff_t delta = 0;
+ if (_heap_pointers_need_patching) {
+ // dumptime heap end ------------v
+ // [ |archived heap regions| ] runtime heap end ------v
+ // [ |archived heap regions| ]
+ // |<-----delta-------------------->|
+ //
+ // At dump time, the archived heap regions were near the top of the heap.
+ // At run time, they may not be inside the heap, so we move them so
+ // that they are now near the top of the runtime time. This can be done by
+ // the simple math of adding the delta as shown above.
+ address dumptime_heap_end = (address)_header->_heap_reserved.end();
+ address runtime_heap_end = (address)heap_reserved.end();
+ delta = runtime_heap_end - dumptime_heap_end;
+ }
+
+ log_info(cds)("CDS heap data relocation delta = " INTX_FORMAT " bytes", delta);
+ HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift());
+
+ CDSFileMapRegion* si = space_at(MetaspaceShared::first_string);
+ address relocated_strings_bottom = start_address_with_archived_oop_encoding_mode(si);
+ if (!is_aligned(relocated_strings_bottom + delta, HeapRegion::GrainBytes)) {
+ // Align the bottom of the string regions at G1 region boundary. This will avoid
+ // the situation where the highest open region and the lowest string region sharing
+ // the same G1 region. Otherwise we will fail to map the open regions.
+ size_t align = size_t(relocated_strings_bottom) % HeapRegion::GrainBytes;
+ delta -= align;
+ assert(is_aligned(relocated_strings_bottom + delta, HeapRegion::GrainBytes), "must be");
+
+ log_info(cds)("CDS heap data need to be relocated lower by a further " SIZE_FORMAT
+ " bytes to be aligned with HeapRegion::GrainBytes", align);
+
+ HeapShared::init_narrow_oop_decoding(narrow_oop_base() + delta, narrow_oop_shift());
+ _heap_pointers_need_patching = true;
+ }
+
// First, map string regions as closed archive heap regions.
// GC does not write into the regions.
if (map_heap_data(&string_ranges,
MetaspaceShared::first_string,
MetaspaceShared::max_strings,
*** 898,913 ****
&num_open_archive_heap_ranges,
true /* open */)) {
MetaspaceShared::set_open_archive_heap_region_mapped();
}
}
! }
! } else {
! if (log_is_enabled(Info, cds) && space_at(MetaspaceShared::first_string)->_used > 0) {
! log_info(cds)("Cached heap data from the CDS archive is being ignored. UseG1GC, "
! "UseCompressedOops and UseCompressedClassPointers are required.");
! }
}
if (!StringTable::shared_string_mapped()) {
assert(string_ranges == NULL && num_string_ranges == 0, "sanity");
}
--- 1003,1017 ----
&num_open_archive_heap_ranges,
true /* open */)) {
MetaspaceShared::set_open_archive_heap_region_mapped();
}
}
! }
!
! void FileMapInfo::map_heap_regions() {
! if (has_heap_regions()) {
! map_heap_regions_impl();
}
if (!StringTable::shared_string_mapped()) {
assert(string_ranges == NULL && num_string_ranges == 0, "sanity");
}
*** 924,959 ****
int region_num = 0;
for (int i = first;
i < first + max; i++) {
si = space_at(i);
! size_t used = si->_used;
! if (used > 0) {
! size_t size = used;
! char* requested_addr = (char*)((void*)CompressedOops::decode_not_null(
! (narrowOop)si->_addr._offset));
! regions[region_num] = MemRegion((HeapWord*)requested_addr, size / HeapWordSize);
region_num ++;
}
}
if (region_num == 0) {
return false; // no archived java heap data
}
// Check that ranges are within the java heap
if (!G1CollectedHeap::heap()->check_archive_addresses(regions, region_num)) {
! log_info(cds)("UseSharedSpaces: Unable to allocate region, "
! "range is not within java heap.");
return false;
}
// allocate from java heap
if (!G1CollectedHeap::heap()->alloc_archive_regions(
regions, region_num, is_open_archive)) {
! log_info(cds)("UseSharedSpaces: Unable to allocate region, "
! "java heap range is already in use.");
return false;
}
// Map the archived heap data. No need to call MemTracker::record_virtual_memory_type()
// for mapped regions as they are part of the reserved java heap, which is
--- 1028,1061 ----
int region_num = 0;
for (int i = first;
i < first + max; i++) {
si = space_at(i);
! size_t size = si->_used;
! if (size > 0) {
! HeapWord* start = (HeapWord*)start_address_with_archived_oop_encoding_mode(si);
! regions[region_num] = MemRegion(start, size / HeapWordSize);
region_num ++;
+ log_info(cds)("Trying to map heap data: region[%d] at " INTPTR_FORMAT ", size = " SIZE_FORMAT_W(8) " bytes",
+ i, p2i(start), size);
}
}
if (region_num == 0) {
return false; // no archived java heap data
}
// Check that ranges are within the java heap
if (!G1CollectedHeap::heap()->check_archive_addresses(regions, region_num)) {
! log_info(cds)("UseSharedSpaces: Unable to allocate region, range is not within java heap.");
return false;
}
// allocate from java heap
if (!G1CollectedHeap::heap()->alloc_archive_regions(
regions, region_num, is_open_archive)) {
! log_info(cds)("UseSharedSpaces: Unable to allocate region, java heap range is already in use.");
return false;
}
// Map the archived heap data. No need to call MemTracker::record_virtual_memory_type()
// for mapped regions as they are part of the reserved java heap, which is
*** 965,975 ****
addr, regions[i].byte_size(), si->_read_only,
si->_allow_exec);
if (base == NULL || base != addr) {
// dealloc the regions from java heap
dealloc_archive_heap_regions(regions, region_num, is_open_archive);
! log_info(cds)("UseSharedSpaces: Unable to map at required address in java heap.");
return false;
}
}
if (!verify_mapped_heap_regions(first, region_num)) {
--- 1067,1079 ----
addr, regions[i].byte_size(), si->_read_only,
si->_allow_exec);
if (base == NULL || base != addr) {
// dealloc the regions from java heap
dealloc_archive_heap_regions(regions, region_num, is_open_archive);
! log_info(cds)("UseSharedSpaces: Unable to map at required address in java heap. "
! INTPTR_FORMAT ", size = " SIZE_FORMAT " bytes",
! p2i(addr), regions[i].byte_size());
return false;
}
}
if (!verify_mapped_heap_regions(first, region_num)) {
*** 993,1002 ****
--- 1097,1131 ----
}
}
return true;
}
+ void FileMapInfo::patch_archived_heap_embedded_pointers() {
+ if (!_heap_pointers_need_patching) {
+ return;
+ }
+
+ patch_archived_heap_embedded_pointers(string_ranges,
+ num_string_ranges,
+ MetaspaceShared::first_string);
+
+ patch_archived_heap_embedded_pointers(open_archive_heap_ranges,
+ num_open_archive_heap_ranges,
+ MetaspaceShared::first_open_archive_heap_region);
+ }
+
+ void FileMapInfo::patch_archived_heap_embedded_pointers(MemRegion* ranges, int num_ranges,
+ int first_region_idx) {
+ for (int i=0; i<num_ranges; i++) {
+ CDSFileMapRegion* si = space_at(i + first_region_idx);
+ HeapShared::patch_archived_heap_embedded_pointers(ranges[i], (address)si->_oopmap,
+ si->_oopmap_size_in_bits);
+ }
+ }
+
+ // This internally allocates objects using SystemDictionary::Object_klass(), so it
+ // must be called after the well-known classes are resolved.
void FileMapInfo::fixup_mapped_heap_regions() {
// If any string regions were found, call the fill routine to make them parseable.
// Note that string_ranges may be non-NULL even if no ranges were found.
if (num_string_ranges != 0) {
assert(string_ranges != NULL, "Null string_ranges array with non-zero count");
*** 1035,1045 ****
!StringTable::shared_string_mapped()) ||
(MetaspaceShared::is_open_archive_heap_region(i) &&
!MetaspaceShared::open_archive_heap_region_mapped())) {
return true; // archived heap data is not mapped
}
! const char* buf = _header->region_addr(i);
int crc = ClassLoader::crc32(0, buf, (jint)sz);
if (crc != space_at(i)->_crc) {
fail_continue("Checksum verification failed.");
return false;
}
--- 1164,1174 ----
!StringTable::shared_string_mapped()) ||
(MetaspaceShared::is_open_archive_heap_region(i) &&
!MetaspaceShared::open_archive_heap_region_mapped())) {
return true; // archived heap data is not mapped
}
! const char* buf = region_addr(i);
int crc = ClassLoader::crc32(0, buf, (jint)sz);
if (crc != space_at(i)->_crc) {
fail_continue("Checksum verification failed.");
return false;
}
*** 1056,1066 ****
if (used == 0) {
return;
}
! char* addr = _header->region_addr(i);
if (!os::unmap_memory(addr, size)) {
fail_stop("Unable to unmap shared space.");
}
}
--- 1185,1195 ----
if (used == 0) {
return;
}
! char* addr = region_addr(i);
if (!os::unmap_memory(addr, size)) {
fail_stop("Unable to unmap shared space.");
}
}
*** 1077,1086 ****
--- 1206,1216 ----
}
}
FileMapInfo* FileMapInfo::_current_info = NULL;
+ bool FileMapInfo::_heap_pointers_need_patching = false;
Array<u8>* FileMapInfo::_shared_path_table = NULL;
int FileMapInfo::_shared_path_table_size = 0;
size_t FileMapInfo::_shared_path_entry_size = 0x1234baad;
bool FileMapInfo::_validating_shared_path_table = false;
*** 1106,1121 ****
return false;
}
return true;
}
! char* FileMapHeader::region_addr(int idx) {
if (MetaspaceShared::is_heap_region(idx)) {
! return _space[idx]._used > 0 ?
! (char*)((void*)CompressedOops::decode_not_null((narrowOop)_space[idx]._addr._offset)) : NULL;
} else {
! return _space[idx]._addr._base;
}
}
int FileMapHeader::compute_crc() {
char* start = (char*)this;
--- 1236,1253 ----
return false;
}
return true;
}
! char* FileMapInfo::region_addr(int idx) {
! CDSFileMapRegion* si = space_at(idx);
if (MetaspaceShared::is_heap_region(idx)) {
! assert(DumpSharedSpaces, "The following doesn't work at runtime");
! return si->_used > 0 ?
! (char*)start_address_with_current_oop_encoding_mode(si) : NULL;
} else {
! return si->_addr._base;
}
}
int FileMapHeader::compute_crc() {
char* start = (char*)this;
*** 1215,1256 ****
bool FileMapInfo::is_in_shared_region(const void* p, int idx) {
assert(idx == MetaspaceShared::ro ||
idx == MetaspaceShared::rw ||
idx == MetaspaceShared::mc ||
idx == MetaspaceShared::md, "invalid region index");
! char* base = _header->region_addr(idx);
if (p >= base && p < base + space_at(idx)->_used) {
return true;
}
return false;
}
- void FileMapInfo::print_shared_spaces() {
- tty->print_cr("Shared Spaces:");
- for (int i = 0; i < MetaspaceShared::n_regions; i++) {
- CDSFileMapRegion* si = space_at(i);
- char *base = _header->region_addr(i);
- tty->print(" %s " INTPTR_FORMAT "-" INTPTR_FORMAT,
- shared_region_name[i],
- p2i(base), p2i(base + si->_used));
- }
- }
-
// Unmap mapped regions of shared space.
void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
MetaspaceObj::set_shared_metaspace_range(NULL, NULL);
FileMapInfo *map_info = FileMapInfo::current_info();
if (map_info) {
map_info->fail_continue("%s", msg);
for (int i = 0; i < MetaspaceShared::num_non_heap_spaces; i++) {
! char *addr = map_info->_header->region_addr(i);
! if (addr != NULL && !MetaspaceShared::is_heap_region(i)) {
map_info->unmap_region(i);
map_info->space_at(i)->_addr._base = NULL;
}
}
// Dealloc the archive heap regions only without unmapping. The regions are part
// of the java heap. Unmapping of the heap regions are managed by GC.
map_info->dealloc_archive_heap_regions(open_archive_heap_ranges,
num_open_archive_heap_ranges,
true);
--- 1347,1379 ----
bool FileMapInfo::is_in_shared_region(const void* p, int idx) {
assert(idx == MetaspaceShared::ro ||
idx == MetaspaceShared::rw ||
idx == MetaspaceShared::mc ||
idx == MetaspaceShared::md, "invalid region index");
! char* base = region_addr(idx);
if (p >= base && p < base + space_at(idx)->_used) {
return true;
}
return false;
}
// Unmap mapped regions of shared space.
void FileMapInfo::stop_sharing_and_unmap(const char* msg) {
MetaspaceObj::set_shared_metaspace_range(NULL, NULL);
FileMapInfo *map_info = FileMapInfo::current_info();
if (map_info) {
map_info->fail_continue("%s", msg);
for (int i = 0; i < MetaspaceShared::num_non_heap_spaces; i++) {
! if (!MetaspaceShared::is_heap_region(i)) {
! char *addr = map_info->region_addr(i);
! if (addr != NULL) {
map_info->unmap_region(i);
map_info->space_at(i)->_addr._base = NULL;
}
}
+ }
// Dealloc the archive heap regions only without unmapping. The regions are part
// of the java heap. Unmapping of the heap regions are managed by GC.
map_info->dealloc_archive_heap_regions(open_archive_heap_ranges,
num_open_archive_heap_ranges,
true);
< prev index next >