--- old/share/memory/virtualspace.cpp 2018-06-12 04:14:37.071190860 -0700 +++ new/share/memory/virtualspace.cpp 2018-06-12 04:14:37.031190859 -0700 @@ -35,11 +35,13 @@ // ReservedSpace // Dummy constructor -ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0), - _alignment(0), _special(false), _executable(false), _fd_for_heap(-1) { +ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0), + _nvdimm_base_nv(NULL), _nvdimm_size(0), _dram_size(0), + _alignment(0), _special(false), _executable(false), _fd_for_heap(-1), _fd_for_nvdimm(-1) { } -ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) : _fd_for_heap(-1) { +ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) : _fd_for_heap(-1), _fd_for_nvdimm(-1), + _nvdimm_base_nv(NULL), _nvdimm_size(0), _dram_size(0) { 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); @@ -60,13 +62,15 @@ ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, - char* requested_address) : _fd_for_heap(-1) { + char* requested_address) : _fd_for_heap(-1), _fd_for_nvdimm(-1), + _nvdimm_base_nv(NULL), _nvdimm_size(0), _dram_size(0) { initialize(size, alignment, large, requested_address, false); } ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, - bool executable) : _fd_for_heap(-1) { + bool executable) : _fd_for_heap(-1), _fd_for_nvdimm(-1), + _nvdimm_base_nv(NULL), _nvdimm_size(0), _dram_size(0) { initialize(size, alignment, large, NULL, executable); } @@ -143,6 +147,7 @@ } char* base = NULL; + char* nvdimm_base = NULL; if (special) { @@ -184,7 +189,11 @@ base = NULL; } } else { - base = os::reserve_memory(size, NULL, alignment, _fd_for_heap); + if (_nvdimm_base_nv != NULL && _fd_for_nvdimm != -1) { + base = os::reserve_memory(_dram_size, _nvdimm_base_nv, alignment, _fd_for_heap); + } else { + base = os::reserve_memory(size, NULL, alignment, _fd_for_heap); + } } if (base == NULL) return; @@ -210,6 +219,9 @@ } // Done _base = base; + _nvdimm_base = _base-_nvdimm_size; + _nvdimm_base_nv = NULL; + _dram_size = (size_t)size; _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 @@ -225,13 +237,15 @@ "size not allocation aligned"); _base = base; _size = size; + _nvdimm_base = NULL; + _nvdimm_base_nv = NULL; + _dram_size = (size_t)size; _alignment = alignment; _noaccess_prefix = 0; _special = special; _executable = executable; } - ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment, bool split, bool realloc) { assert(partition_size <= size(), "partition failed"); @@ -277,6 +291,10 @@ if (is_reserved()) { char *real_base = _base - _noaccess_prefix; const size_t real_size = _size + _noaccess_prefix; + // unmap nvdimm + if (_fd_for_nvdimm != -1) { + os::unmap_memory(real_base+real_size, _nvdimm_size); + } if (special()) { if (_fd_for_heap != -1) { os::unmap_memory(real_base, real_size); @@ -287,6 +305,10 @@ os::release_memory(real_base, real_size); } _base = NULL; + _nvdimm_base = NULL; + _nvdimm_base_nv = NULL; + _dram_size = 0; + _nvdimm_size = 0; _size = 0; _noaccess_prefix = 0; _alignment = 0; @@ -341,6 +363,12 @@ release(); } + if (_fd_for_nvdimm != -1 && UseG1GC) { + char* base_nv = os::reserve_memory(size, requested_address, alignment); + initialize_g1gc_nvdimm_dram_sizes(size, alignment); + _nvdimm_base_nv = base_nv+_nvdimm_size; // hint for allocation address of DRAM COMPRESSED HEAP. + } + // 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. // If there is a backing file directory for this space then whether @@ -355,6 +383,7 @@ } } char* base = NULL; + char* nvdimm_base = NULL; log_trace(gc, heap, coops)("Trying to allocate at address " PTR_FORMAT " heap of size " SIZE_FORMAT_HEX, @@ -390,16 +419,33 @@ // important. If available space is not detected, return NULL. if (requested_address != 0) { - base = os::attempt_reserve_memory_at(size, requested_address, _fd_for_heap); + if (_nvdimm_base_nv != NULL && _fd_for_nvdimm != -1) { + // first unmap so that OS does not keep trying. + os::unmap_memory(_nvdimm_base_nv, _dram_size); + base = os::attempt_reserve_memory_at(_dram_size, _nvdimm_base_nv); + } else { + base = os::attempt_reserve_memory_at(size, requested_address, _fd_for_heap); + } } else { - base = os::reserve_memory(size, NULL, alignment, _fd_for_heap); + if (_nvdimm_base_nv != NULL && _fd_for_nvdimm != -1) { + // first unmap so that OS does not keep trying. + os::unmap_memory(_nvdimm_base_nv, _dram_size); + base = os::reserve_memory(_dram_size, _nvdimm_base_nv, alignment); + } else { + base = os::reserve_memory(size, NULL, alignment, _fd_for_heap); + } } } if (base == NULL) { return; } // Done _base = base; - _size = size; + _nvdimm_base = _base-_nvdimm_size; + if (_nvdimm_base_nv != NULL && _fd_for_nvdimm != -1) { + _size = _dram_size; + } else { + _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 @@ -601,12 +647,41 @@ } } +void ReservedHeapSpace::initialize_g1gc_nvdimm_dram_sizes(size_t size, size_t alignment) { + _dram_size = (size_t)((size * G1MaxNewSizePercent)/100); + size_t page_sz = os::vm_page_size() -1 ; + _dram_size = (_dram_size + page_sz) & (~page_sz); + // align sizes. + _dram_size = align_down(_dram_size, alignment); + _nvdimm_size = size - _dram_size; + _nvdimm_size = (_nvdimm_size + page_sz) & (~page_sz); + _nvdimm_size = align_down(_nvdimm_size, alignment); +} + ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment, bool large, const char* heap_allocation_directory) : ReservedSpace() { if (size == 0) { return; } + // if AllocateOldGen is used + if (AllocateOldGenAt != NULL) { + _fd_for_nvdimm = os::create_file_for_heap(AllocateOldGenAt); + if (_fd_for_nvdimm == -1) { + vm_exit_during_initialization( + err_msg("Could not create file for Heap at location %s", AllocateOldGenAt)); + } + if (UseParallelOldGC) { + // For ParallelOldGC, adaptive sizing picks _old_gen virtual space sizes as needed. + // allocate Xmx on NVDIMM as adaptive sizing may put lot of pressure on NVDIMM. + os::allocate_file(_fd_for_nvdimm, MaxHeapSize); + os::set_nvdimm_fd(_fd_for_nvdimm); + os::set_nvdimm_present(true); + } + } else { + _fd_for_nvdimm = -1; + } + if (heap_allocation_directory != NULL) { _fd_for_heap = os::create_file_for_heap(heap_allocation_directory); if (_fd_for_heap == -1) { @@ -618,6 +693,18 @@ // Heap size should be aligned to alignment, too. guarantee(is_aligned(size, alignment), "set by caller"); + char* base_nv = NULL; + _nvdimm_base_nv = NULL; + + if (_fd_for_nvdimm != -1 && UseG1GC) { + if (!UseCompressedOops) { + // if compressed oops use requested address. + initialize_g1gc_nvdimm_dram_sizes(size, alignment); + base_nv = os::reserve_memory(size, NULL, alignment); + _nvdimm_base_nv = base_nv+_nvdimm_size; // hint for allocation address of DRAM heap + } + } + if (UseCompressedOops) { initialize_compressed_heap(size, alignment, large); if (_size > size) { @@ -627,7 +714,11 @@ establish_noaccess_prefix(); } } else { - initialize(size, alignment, large, NULL, false); + if (_fd_for_nvdimm != -1 && UseG1GC) { + initialize(_dram_size, alignment, large, NULL, false); + } else { + initialize(size, alignment, large, NULL, false); + } } assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base, @@ -637,6 +728,15 @@ if (base() != NULL) { MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap); + if (_fd_for_nvdimm != -1 && UseG1GC) { + os::set_nvdimm_present(true); + os::set_dram_heapbase((address)_base); + os::set_nvdimm_heapbase((address)_nvdimm_base); + os::set_nvdimm_fd(_fd_for_nvdimm); + _size += _nvdimm_size; + _base = _nvdimm_base; + log_info(gc, heap)("Java DRAM Heap at [%p - %p] & NVDIMM Old Gen at [%p - %p] %ld \n", _nvdimm_base+_nvdimm_size, (char*)(_nvdimm_base+_nvdimm_size+_dram_size), _nvdimm_base, (char*)(_nvdimm_base+_nvdimm_size), size); + } } if (_fd_for_heap != -1) {