--- /dev/null 2019-09-04 10:58:08.784555846 -0700 +++ new/src/hotspot/share/gc/g1/g1MemoryNodeManager.cpp 2019-09-21 06:25:32.357961342 -0700 @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc/g1/heapRegionType.hpp" +#include "gc/g1/g1MemoryNodeManager.hpp" +#include "gc/g1/g1NUMA.inline.hpp" + +G1MemoryNodeManager* G1MemoryNodeManager::_inst = NULL; + +class G1MemoryMultiNodeManager : public G1MemoryNodeManager { + G1NUMA* _numa; + +public: + // The given numa instance will be deleted by the destructor. + G1MemoryMultiNodeManager(G1NUMA* numa); + ~G1MemoryMultiNodeManager(); + + virtual void set_page_size(size_t page_size); + + virtual uint num_active_nodes() const; + + virtual const int* node_ids() const; + + virtual uint index_of_current_thread() const; + + virtual uint valid_node_index(uint node_index) const; + + virtual bool is_valid_node_index(uint node_index) const; + + virtual uint index_of_address(HeapWord* addr) const; +}; + +G1MemoryNodeManager* G1MemoryNodeManager::create() { + guarantee(_inst == NULL, "Should be called once."); + + // Use multi node manager: + // 1. If UseNUMA is enabled + // 2. If there are more than 1 active numa nodes. + // Doesn't support multi node manager for Solaris. + if (UseNUMA SOLARIS_ONLY(&& false)) { + // Create G1NUMA to check current active numa nodes. + G1NUMA* numa = new G1NUMA(); + + if (numa != NULL) { + numa->initialize(); + + if (numa->num_active_numa_ids() > 1) { + G1NUMA::set_numa(numa); + _inst = new G1MemoryMultiNodeManager(numa); + return _inst; + } + + delete numa; + } + } + + _inst = new G1MemoryNodeManager(); + + return _inst; +} + +G1MemoryMultiNodeManager::G1MemoryMultiNodeManager(G1NUMA* numa) : _numa(numa) { } + +G1MemoryMultiNodeManager::~G1MemoryMultiNodeManager() { + delete _numa; +} + +void G1MemoryMultiNodeManager::set_page_size(size_t page_size) { + _numa->set_page_size(page_size); +} + +uint G1MemoryMultiNodeManager::num_active_nodes() const { + return _numa->num_active_numa_ids(); +} + +const int* G1MemoryMultiNodeManager::node_ids() const { + return _numa->numa_ids(); +} + +uint G1MemoryMultiNodeManager::index_of_current_thread() const { + int node_id = os::numa_get_group_id(); + return _numa->index_of_numa_id(node_id); +} + +uint G1MemoryMultiNodeManager::valid_node_index(uint node_index) const { + if (!_numa->is_valid_numa_index(node_index)) { + node_index = _numa->next_numa_index(); + } + return node_index; +} + +bool G1MemoryMultiNodeManager::is_valid_node_index(uint node_index) const { + return _numa->is_valid_numa_index(node_index); +} + +uint G1MemoryMultiNodeManager::index_of_address(HeapWord* addr) const { + return _numa->index_of_address(addr); +}