--- old/src/hotspot/os/linux/os_linux.cpp 2019-10-15 07:17:50.702090789 -0700 +++ new/src/hotspot/os/linux/os_linux.cpp 2019-10-15 07:17:50.322090777 -0700 @@ -3019,7 +3019,7 @@ #ifndef MPOL_F_ADDR #define MPOL_F_ADDR (1<<1) // Look up VMA using address #endif - + int id = InvalidNUMAId; if (syscall(SYS_get_mempolicy, &id, NULL, 0, address, MPOL_F_NODE | MPOL_F_ADDR) == -1) { --- old/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2019-10-15 07:17:51.878090825 -0700 +++ new/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2019-10-15 07:17:51.502090813 -0700 @@ -1797,7 +1797,7 @@ } _workers->initialize_workers(); - _numa->set_region_info(g1_rs.base(), HeapRegion::GrainBytes, page_size); + _numa->set_region_info(HeapRegion::GrainBytes, page_size); // Create the G1ConcurrentMark data structure and thread. // (Must do this late, so that "max_regions" is defined.) --- old/src/hotspot/share/gc/g1/g1NUMA.cpp 2019-10-15 07:17:52.918090857 -0700 +++ new/src/hotspot/share/gc/g1/g1NUMA.cpp 2019-10-15 07:17:52.546090846 -0700 @@ -31,11 +31,6 @@ G1NUMA* G1NUMA::_inst = NULL; -void* G1NUMA::base_address() const { - assert(_base_address != NULL, "Base address is not yet set"); - return _base_address; -} - size_t G1NUMA::region_size() const { assert(_region_size > 0, "Heap region size is not yet set"); return _region_size; @@ -79,7 +74,7 @@ G1NUMA::G1NUMA() : _node_id_to_index_map(NULL), _len_node_id_to_index_map(0), _node_ids(NULL), _num_active_node_ids(0), - _base_address(NULL), _region_size(0), _page_size(0) { + _region_size(0), _page_size(0) { } void G1NUMA::initialize_without_numa() { @@ -131,8 +126,7 @@ FREE_C_HEAP_ARRAY(int, _node_ids); } -void G1NUMA::set_region_info(void* base_address, size_t region_size, size_t page_size) { - _base_address = base_address; +void G1NUMA::set_region_info(size_t region_size, size_t page_size) { _region_size = region_size; _page_size = page_size; } @@ -203,28 +197,25 @@ // * Page #: |-----0----||-----1----||-----2----||-----3----||-----4----||-----5----||-----6----||-----7----| // * HeapRegion #: |-#0-||-#1-||-#2-||-#3-||-#4-||-#5-||-#6-||-#7-||-#8-||-#9-||#10-||#11-||#12-||#13-||#14-||#15-| // * NUMA node #: |----#0----||----#1----||----#2----||----#3----||----#0----||----#1----||----#2----||----#3----| -void G1NUMA::request_memory_on_node(size_t start_page, size_t size_in_pages, uint region_index) { +void G1NUMA::request_memory_on_node(void* aligned_address, size_t size_in_bytes, uint region_index) { if (!is_enabled()) { return; } - if (size_in_pages == 0) { + if (size_in_bytes == 0) { return; } - char* aligned_address = (char*)base_address() + start_page * page_size(); - size_t size_in_bytes = size_in_pages * page_size(); uint node_index = preferred_node_index_for_index(region_index); assert(is_aligned(aligned_address, page_size()), "Given address (" PTR_FORMAT ") should be aligned.", p2i(aligned_address)); assert(is_aligned(size_in_bytes, page_size()), "Given size (" SIZE_FORMAT ") should be aligned.", size_in_bytes); log_debug(gc, heap, numa)("Request memory [" PTR_FORMAT ", " PTR_FORMAT ") to be numa id (%d).", - p2i(aligned_address), p2i(aligned_address + size_in_bytes), _node_ids[node_index]); - os::numa_make_local(aligned_address, size_in_bytes, _node_ids[node_index]); + p2i(aligned_address), p2i((char*)aligned_address + size_in_bytes), _node_ids[node_index]); + os::numa_make_local((char*)aligned_address, size_in_bytes, _node_ids[node_index]); } - uint G1NUMA::max_search_depth() const { // Multiple of 3 is just random number to limit iterations. // There would be some cases that 1 page may be consisted of multiple HeapRegions. --- old/src/hotspot/share/gc/g1/g1NUMA.hpp 2019-10-15 07:17:53.758090883 -0700 +++ new/src/hotspot/share/gc/g1/g1NUMA.hpp 2019-10-15 07:17:53.390090872 -0700 @@ -44,14 +44,11 @@ // Total number of node ids. uint _num_active_node_ids; - // Base address of Java heap - void* _base_address; // HeapRegion size size_t _region_size; // Necessary when touching memory. size_t _page_size; - void* base_address() const; size_t region_size() const; size_t page_size() const; @@ -78,11 +75,11 @@ ~G1NUMA(); - // Set base address of heap, heap region size and page size after those values - // are determined at G1CollectedHeap::initialize(). - void set_region_info(void* base_address, size_t region_size, size_t page_size); + // Sets heap region size and page size after those values + // are determined at G1CollectedHeap::initialize(). + void set_region_info(size_t region_size, size_t page_size); - // Print current active memory node count. + // Returns active memory node count. uint num_active_nodes() const; bool is_enabled() const; @@ -101,7 +98,7 @@ // Result is less than num_active_nodes(). uint preferred_node_index_for_index(uint region_index) const; - // Retrieve node index of the given address. + // Retrieves node index of the given address. // Result is less than num_active_nodes() or is UnknownNodeIndex. // Precondition: address is in reserved range for heap. uint index_of_address(HeapWord* address) const; @@ -110,8 +107,8 @@ // If disabled, return preferred node index of the given heap region. uint index_for_region(HeapRegion* hr) const; - // Request the given memory area to be located at the given node index. - void request_memory_on_node(size_t start_page, size_t size_in_pages, uint region_index); + // Requests the given memory area to be located at the given node index. + void request_memory_on_node(void* aligned_address, size_t size_in_bytes, uint region_index); // Returns maximum search depth which is used to limit heap region search iterations. // The number of active nodes, page size and heap region size are considered. --- old/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp 2019-10-15 07:17:54.706090912 -0700 +++ new/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp 2019-10-15 07:17:54.334090901 -0700 @@ -289,6 +289,11 @@ return _low_boundary <= (const char*) p && (const char*) p < _high_boundary; } +size_t G1PageBasedVirtualSpace::page_size() const { + assert(_page_size > 0, "Page size is not yet initialized."); + return _page_size; +} + #ifndef PRODUCT void G1PageBasedVirtualSpace::print_on(outputStream* out) { out->print ("Virtual space:"); --- old/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp 2019-10-15 07:17:55.778090945 -0700 +++ new/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.hpp 2019-10-15 07:17:55.406090934 -0700 @@ -92,8 +92,6 @@ // Returns the index of the page which contains the given address. size_t addr_to_page_index(char* addr) const; - // Returns the address of the given page index. - char* page_start(size_t index) const; // Is the given page index the last page? bool is_last_page(size_t index) const { return index == (_committed.size() - 1); } @@ -147,6 +145,10 @@ void check_for_contiguity() PRODUCT_RETURN; + // Returns the address of the given page index. + char* page_start(size_t index) const; + size_t page_size() const; + // Debugging void print_on(outputStream* out) PRODUCT_RETURN; void print(); --- old/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp 2019-10-15 07:17:56.710090974 -0700 +++ new/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.cpp 2019-10-15 07:17:56.334090962 -0700 @@ -45,7 +45,8 @@ _listener(NULL), _storage(rs, used_size, page_size), _region_granularity(region_granularity), - _commit_map(rs.size() * commit_factor / region_granularity, mtGC) { + _commit_map(rs.size() * commit_factor / region_granularity, mtGC), + _memory_type(type) { guarantee(is_power_of_2(page_size), "must be"); guarantee(is_power_of_2(region_granularity), "must be"); @@ -76,9 +77,12 @@ const size_t start_page = (size_t)start_idx * _pages_per_region; const size_t size_in_pages = num_regions * _pages_per_region; bool zero_filled = _storage.commit(start_page, size_in_pages); - for (uint region_index = start_idx; region_index < start_idx + num_regions; region_index++ ) { - size_t page = region_index * _pages_per_region; - G1NUMA::numa()->request_memory_on_node(page, _pages_per_region, region_index); + if (_memory_type == mtJavaHeap) { + for (uint region_index = start_idx; region_index < start_idx + num_regions; region_index++ ) { + void* address = _storage.page_start(region_index * _pages_per_region); + size_t size_in_bytes = _storage.page_size() * _pages_per_region; + G1NUMA::numa()->request_memory_on_node(address, size_in_bytes, region_index); + } } if (AlwaysPreTouch) { _storage.pretouch(start_page, size_in_pages, pretouch_gang); @@ -134,26 +138,30 @@ bool all_zero_filled = true; G1NUMA* numa = G1NUMA::numa(); - for (uint i = start_idx; i < start_idx + num_regions; i++) { - assert(!_commit_map.at(i), "Trying to commit storage at region %u that is already committed", i); - size_t idx = region_idx_to_page_idx(i); - uint old_refcount = _refcounts.get_by_index(idx); + for (uint region_idx = start_idx; region_idx < start_idx + num_regions; region_idx++) { + assert(!_commit_map.at(region_idx), "Trying to commit storage at region %u that is already committed", region_idx); + size_t page_idx = region_idx_to_page_idx(region_idx); + uint old_refcount = _refcounts.get_by_index(page_idx); bool zero_filled = false; if (old_refcount == 0) { if (first_committed == NoPage) { - first_committed = idx; + first_committed = page_idx; num_committed = 1; } else { num_committed++; } - zero_filled = _storage.commit(idx, 1); - numa->request_memory_on_node(idx, 1, i); + zero_filled = _storage.commit(page_idx, 1); + if (_memory_type == mtJavaHeap) { + void* address = _storage.page_start(page_idx); + size_t size_in_bytes = _storage.page_size(); + numa->request_memory_on_node(address, size_in_bytes, region_idx); + } } all_zero_filled &= zero_filled; - _refcounts.set_by_index(idx, old_refcount + 1); - _commit_map.set_bit(i); + _refcounts.set_by_index(page_idx, old_refcount + 1); + _commit_map.set_bit(region_idx); } if (AlwaysPreTouch && num_committed > 0) { _storage.pretouch(first_committed, num_committed, pretouch_gang); --- old/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp 2019-10-15 07:17:57.682091004 -0700 +++ new/src/hotspot/share/gc/g1/g1RegionToSpaceMapper.hpp 2019-10-15 07:17:57.306090992 -0700 @@ -53,6 +53,8 @@ // Mapping management CHeapBitMap _commit_map; + MemoryType _memory_type; + G1RegionToSpaceMapper(ReservedSpace rs, size_t used_size, size_t page_size, size_t region_granularity, size_t commit_factor, MemoryType type); void fire_on_commit(uint start_idx, size_t num_regions, bool zero_filled);