1 /* 2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "gc/g1/heapRegionType.hpp" 27 #include "gc/g1/g1MemoryNodeManager.hpp" 28 #include "gc/g1/g1NUMA.inline.hpp" 29 30 G1MemoryNodeManager* G1MemoryNodeManager::_inst = NULL; 31 32 const int* G1MemoryNodeManager::node_ids() const { 33 static const int dummy_id = 0; 34 return &dummy_id; 35 } 36 37 class G1MemoryMultiNodeManager : public G1MemoryNodeManager { 38 G1NUMA* _numa; 39 40 public: 41 // The given numa instance will be deleted by the destructor. 42 G1MemoryMultiNodeManager(G1NUMA* numa); 43 ~G1MemoryMultiNodeManager(); 44 45 virtual void set_page_size(size_t page_size); 46 47 virtual uint num_active_nodes() const; 48 49 virtual const int* node_ids() const; 50 51 virtual uint index_of_current_thread() const; 52 53 virtual bool is_valid_node_index(uint node_index) const; 54 55 virtual uint preferred_index_for_address(HeapWord* addr) const; 56 57 virtual uint index_of_address(HeapWord* addr) const; 58 }; 59 60 G1MemoryNodeManager* G1MemoryNodeManager::create() { 61 guarantee(_inst == NULL, "Should be called once."); 62 63 // Use multi node manager: 64 // 1. On Linux 65 // 2. If UseNUMA is enabled 66 // 3. If there are more than 1 active numa nodes. 67 LINUX_ONLY(if (UseNUMA) { 68 // Create G1NUMA to check current active numa nodes. 69 G1NUMA* numa = new G1NUMA(); 70 71 numa->initialize(); 72 73 if (numa->num_active_numa_ids() > 1) { 74 G1NUMA::set_numa(numa); 75 _inst = new G1MemoryMultiNodeManager(numa); 76 return _inst; 77 } 78 79 delete numa; 80 }) 81 82 _inst = new G1MemoryNodeManager(); 83 84 return _inst; 85 } 86 87 G1MemoryMultiNodeManager::G1MemoryMultiNodeManager(G1NUMA* numa) : _numa(numa) { } 88 89 G1MemoryMultiNodeManager::~G1MemoryMultiNodeManager() { 90 delete _numa; 91 } 92 93 void G1MemoryMultiNodeManager::set_page_size(size_t page_size) { 94 _numa->set_page_size(page_size); 95 } 96 97 uint G1MemoryMultiNodeManager::num_active_nodes() const { 98 return _numa->num_active_numa_ids(); 99 } 100 101 const int* G1MemoryMultiNodeManager::node_ids() const { 102 return _numa->numa_ids(); 103 } 104 105 uint G1MemoryMultiNodeManager::index_of_current_thread() const { 106 return _numa->index_of_current_thread(); 107 } 108 109 bool G1MemoryMultiNodeManager::is_valid_node_index(uint node_index) const { 110 return _numa->is_valid_numa_index(node_index); 111 } 112 113 uint G1MemoryMultiNodeManager::preferred_index_for_address(HeapWord* addr) const { 114 return _numa->preferred_index_for_address(addr); 115 } 116 117 uint G1MemoryMultiNodeManager::index_of_address(HeapWord* addr) const { 118 return _numa->index_of_address(addr); 119 }