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 class G1MemoryMultiNodeManager : public G1MemoryNodeManager { 33 G1NUMA* _numa; 34 35 public: 36 // The given numa instance will be deleted by the destructor. 37 G1MemoryMultiNodeManager(G1NUMA* numa); 38 ~G1MemoryMultiNodeManager(); 39 40 virtual void set_page_size(size_t page_size); 41 42 virtual uint num_active_nodes() const; 43 44 virtual const int* node_ids() const; 45 46 virtual uint index_of_current_thread() const; 47 48 virtual uint valid_node_index(uint node_index) const; 49 50 virtual bool is_valid_node_index(uint node_index) const; 51 52 virtual uint index_of_address(HeapWord* addr) const; 53 }; 54 55 G1MemoryNodeManager* G1MemoryNodeManager::create() { 56 guarantee(_inst == NULL, "Should be called once."); 57 58 // Use multi node manager: 59 // 1. If UseNUMA is enabled 60 // 2. If there are more than 1 active numa nodes. 61 // Doesn't support multi node manager for Solaris. 62 if (UseNUMA SOLARIS_ONLY(&& false)) { 63 // Create G1NUMA to check current active numa nodes. 64 G1NUMA* numa = new G1NUMA(); 65 66 if (numa != NULL) { 67 numa->initialize(); 68 69 if (numa->num_active_numa_ids() > 1) { 70 G1NUMA::set_numa(numa); 71 _inst = new G1MemoryMultiNodeManager(numa); 72 return _inst; 73 } 74 75 delete numa; 76 } 77 } 78 79 _inst = new G1MemoryNodeManager(); 80 81 return _inst; 82 } 83 84 G1MemoryMultiNodeManager::G1MemoryMultiNodeManager(G1NUMA* numa) : _numa(numa) { } 85 86 G1MemoryMultiNodeManager::~G1MemoryMultiNodeManager() { 87 delete _numa; 88 } 89 90 void G1MemoryMultiNodeManager::set_page_size(size_t page_size) { 91 _numa->set_page_size(page_size); 92 } 93 94 uint G1MemoryMultiNodeManager::num_active_nodes() const { 95 return _numa->num_active_numa_ids(); 96 } 97 98 const int* G1MemoryMultiNodeManager::node_ids() const { 99 return _numa->numa_ids(); 100 } 101 102 uint G1MemoryMultiNodeManager::index_of_current_thread() const { 103 int node_id = os::numa_get_group_id(); 104 return _numa->index_of_numa_id(node_id); 105 } 106 107 uint G1MemoryMultiNodeManager::valid_node_index(uint node_index) const { 108 if (!_numa->is_valid_numa_index(node_index)) { 109 node_index = _numa->next_numa_index(); 110 } 111 return node_index; 112 } 113 114 bool G1MemoryMultiNodeManager::is_valid_node_index(uint node_index) const { 115 return _numa->is_valid_numa_index(node_index); 116 } 117 118 uint G1MemoryMultiNodeManager::index_of_address(HeapWord* addr) const { 119 return _numa->index_of_address(addr); 120 }