< prev index next >

share/memory/virtualspace.cpp

Print this page
rev 1 : G1GC+POGC+NVDIMM Patch with latest comments incorporated from all.

*** 34,47 **** // ReservedSpace // Dummy constructor ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0), ! _alignment(0), _special(false), _executable(false), _fd_for_heap(-1) { } ! ReservedSpace::ReservedSpace(size_t size, size_t preferred_page_size) : _fd_for_heap(-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); bool large_pages = page_size != (size_t)os::vm_page_size(); size_t alignment; --- 34,49 ---- // ReservedSpace // Dummy constructor 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), _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); bool large_pages = page_size != (size_t)os::vm_page_size(); size_t alignment;
*** 58,74 **** initialize(size, alignment, large_pages, NULL, false); } ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, ! char* requested_address) : _fd_for_heap(-1) { initialize(size, alignment, large, requested_address, false); } ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, ! bool executable) : _fd_for_heap(-1) { initialize(size, alignment, large, NULL, executable); } // Helper method static void unmap_or_release_memory(char* base, size_t size, bool is_file_mapped) { --- 60,78 ---- initialize(size, alignment, large_pages, NULL, false); } ReservedSpace::ReservedSpace(size_t size, size_t alignment, bool large, ! 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), _fd_for_nvdimm(-1), ! _nvdimm_base_nv(NULL), _nvdimm_size(0), _dram_size(0) { initialize(size, alignment, large, NULL, executable); } // Helper method static void unmap_or_release_memory(char* base, size_t size, bool is_file_mapped) {
*** 141,150 **** --- 145,155 ---- log_debug(gc, heap)("Ignoring UseLargePages since large page support is up to the file system of the backing file for Java heap"); } } char* base = NULL; + char* nvdimm_base = NULL; if (special) { base = os::reserve_memory_special(size, alignment, requested_address, executable);
*** 182,193 **** --- 187,202 ---- if (failed_to_reserve_as_requested(base, requested_address, size, false, _fd_for_heap != -1)) { // OS ignored requested address. Try different address. base = NULL; } } else { + 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; // Check alignment constraints if ((((size_t)base) & (alignment - 1)) != 0) {
*** 208,217 **** --- 217,229 ---- } } } // 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 if (_fd_for_heap != -1) { _special = true;
*** 223,239 **** bool special, bool executable) { assert((size % os::vm_allocation_granularity()) == 0, "size not allocation aligned"); _base = base; _size = 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"); if (split) { os::split_reserved_memory(base(), size(), partition_size, realloc); --- 235,253 ---- bool special, bool executable) { assert((size % os::vm_allocation_granularity()) == 0, "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"); if (split) { os::split_reserved_memory(base(), size(), partition_size, realloc);
*** 275,294 **** --- 289,316 ---- void ReservedSpace::release() { 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); } else { os::release_memory_special(real_base, real_size); } } else{ 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; _special = false; _executable = false;
*** 339,348 **** --- 361,376 ---- if (_base != NULL) { // We tried before, but we didn't like the address delivered. 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 // large pages are allocated is up to the filesystem of the backing file. // So we ignore the UseLargePages flag in this case.
*** 353,362 **** --- 381,391 ---- !FLAG_IS_DEFAULT(LargePageSizeInBytes))) { log_debug(gc, heap)("Cannot allocate large pages for Java Heap when AllocateHeapAt option is set."); } } 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, p2i(requested_address), size);
*** 388,407 **** --- 417,453 ---- // If the memory was requested at a particular address, use // os::attempt_reserve_memory_at() to avoid over mapping something // important. If available space is not detected, return NULL. if (requested_address != 0) { + 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 { + 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; + _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 if (_fd_for_heap != -1) { _special = true;
*** 599,614 **** --- 645,689 ---- initialize(size + noaccess_prefix, alignment, large, NULL, false); } } } + 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) { vm_exit_during_initialization( err_msg("Could not create file for Heap at location %s", heap_allocation_directory));
*** 616,644 **** --- 691,744 ---- } // 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) { // We allocated heap with noaccess prefix. // It can happen we get a zerobased/unscaled heap with noaccess prefix, // if we had to try at arbitrary address. establish_noaccess_prefix(); } } else { + 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, "area must be distinguishable from marks for mark-sweep"); assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size], "area must be distinguishable from marks for mark-sweep"); 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) { os::close(_fd_for_heap); }
< prev index next >