--- old/src/share/vm/memory/virtualspace.cpp 2016-08-15 19:49:19.774365700 -0700 +++ new/src/share/vm/memory/virtualspace.cpp 2016-08-15 19:49:19.361747900 -0700 @@ -35,10 +35,10 @@ // Dummy constructor ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0), - _alignment(0), _special(false), _executable(false) { + _alignment(0), _special(false), _executable(false), _backing_fd(-1) { } -ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) { +ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) : _backing_fd(-1) { bool has_preferred_page_size = preferred_page_size != 0; // Want to use large pages where possible and pad with small pages. size_t page_size = has_preferred_page_size ? preferred_page_size : os::page_size_for_region_unaligned(size, 1); @@ -59,13 +59,13 @@ ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, - char* requested_address) { + char* requested_address) : _backing_fd(-1) { initialize(size, alignment, large, requested_address, false); } ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, - bool executable) { + bool executable) : _backing_fd(-1) { initialize(size, alignment, large, NULL, executable); } @@ -120,7 +120,9 @@ // If OS doesn't support demand paging for large page memory, we need // to use reserve_memory_special() to reserve and pin the entire region. - bool special = large && !os::can_commit_large_page_memory(); + // If there is a backing file directory for this VirtualSpace then whether largepages are allocated is upto the filesystem the dir resides in. + // So we ignore the UseLargePages flag in this case. + bool special = (_backing_fd == -1) && (large && !os::can_commit_large_page_memory()); char* base = NULL; if (special) { @@ -157,13 +159,13 @@ // important. If available space is not detected, return NULL. if (requested_address != 0) { - base = os::attempt_reserve_memory_at(size, requested_address); + base = os::attempt_reserve_memory_at(size, requested_address, _backing_fd); if (failed_to_reserve_as_requested(base, requested_address, size, false)) { // OS ignored requested address. Try different address. base = NULL; } } else { - base = os::reserve_memory(size, NULL, alignment); + base = os::reserve_memory(size, NULL, alignment, _backing_fd); } if (base == NULL) return; @@ -171,10 +173,15 @@ // Check alignment constraints if ((((size_t)base) & (alignment - 1)) != 0) { // Base not aligned, retry - if (!os::release_memory(base, size)) fatal("os::release_memory failed"); + if (_backing_fd != -1) { + if (!os::unmap_memory(base, size)) fatal("os::release_memory failed"); + } + else { + if (!os::release_memory(base, size)) fatal("os::release_memory failed"); + } // Make sure that size is aligned size = align_size_up(size, alignment); - base = os::reserve_memory_aligned(size, alignment); + base = os::reserve_memory_aligned(size, alignment, _backing_fd); if (requested_address != 0 && failed_to_reserve_as_requested(base, requested_address, size, false)) { @@ -190,6 +197,10 @@ _base = base; _size = size; _alignment = alignment; + // If heap is reserved with a backing file, the entire space has been committed. So set the _special flag to true + if (_backing_fd != -1) { + _special = true; + } } @@ -313,7 +324,9 @@ // If OS doesn't support demand paging for large page memory, we need // to use reserve_memory_special() to reserve and pin the entire region. - bool special = large && !os::can_commit_large_page_memory(); + // If there is a backing file directory for this VirtualSpace then whether largepages are allocated is upto the filesystem the dir resides in. + // So we ignore the UseLargePages flag in this case. + bool special = (_backing_fd == -1) && (large && !os::can_commit_large_page_memory()); char* base = NULL; log_trace(gc, heap, coops)("Trying to allocate at address " PTR_FORMAT @@ -350,9 +363,9 @@ // important. If available space is not detected, return NULL. if (requested_address != 0) { - base = os::attempt_reserve_memory_at(size, requested_address); + base = os::attempt_reserve_memory_at(size, requested_address, _backing_fd); } else { - base = os::reserve_memory(size, NULL, alignment); + base = os::reserve_memory(size, NULL, alignment, _backing_fd); } } if (base == NULL) { return; } @@ -361,6 +374,10 @@ _base = base; _size = size; _alignment = alignment; + // If heap is reserved with a backing file, the entire space has been committed. So set the _special flag to true + if (_backing_fd != -1) { + _special = true; + } // Check alignment constraints if ((((size_t)base) & (alignment - 1)) != 0) { @@ -556,12 +573,16 @@ } } -ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, bool large) : ReservedSpace() { +ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, bool large, const char* backingFSforHeap) : ReservedSpace() { if (size == 0) { return; } + if (backingFSforHeap != NULL) { + _backing_fd = os::create_file_for_heap(backingFSforHeap, size); + } + // Heap size should be aligned to alignment, too. guarantee(is_size_aligned(size, alignment), "set by caller"); @@ -585,6 +606,10 @@ if (base() > 0) { MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap); } + + if (backingFSforHeap != NULL) { + os::close(_backing_fd); + } } // Reserve space for code segment. Same as Java heap only we mark this as