--- /dev/null 2019-10-07 09:27:17.753004199 -0700 +++ new/src/hotspot/share/gc/g1/g1NUMA.hpp 2019-10-15 07:18:58.914092893 -0700 @@ -0,0 +1,118 @@ +/* + * 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. + * + */ + +#ifndef SHARE_VM_GC_G1_NUMA_HPP +#define SHARE_VM_GC_G1_NUMA_HPP + +#include "memory/allocation.hpp" +#include "runtime/os.hpp" + +class HeapRegion; + +class G1NUMA: public CHeapObj { + // Mapping of available node ids to 0-based index which can be used for + // fast resource management. I.e. for every node id provides a unique value in + // the range from [0, {# of nodes-1}]. + // For invalid node id, return UnknownNodeIndex. + uint* _node_id_to_index_map; + // Length of _num_active_node_ids_id to index map. + int _len_node_id_to_index_map; + + // Current active node ids. + int* _node_ids; + // Total number of node ids. + uint _num_active_node_ids; + + // HeapRegion size + size_t _region_size; + // Necessary when touching memory. + size_t _page_size; + + size_t region_size() const; + size_t page_size() const; + + // Returns node index of the given node id. + // Precondition: node_id is an active node id. + inline uint index_of_node_id(int node_id) const; + + // Creates node id and node index mapping table of _node_id_to_index_map. + void init_node_id_to_index_map(const int* node_ids, uint num_node_ids); + + static G1NUMA* _inst; + + G1NUMA(); + void initialize(bool use_numa); + void initialize_without_numa(); + +public: + static const uint UnknownNodeIndex = UINT_MAX; + static const uint AnyNodeIndex = UnknownNodeIndex - 1; + + static G1NUMA* numa() { return _inst; } + + static G1NUMA* create(); + + ~G1NUMA(); + + // 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); + + // Returns active memory node count. + uint num_active_nodes() const; + + bool is_enabled() const; + + int numa_id(int index) const; + + // Returns memory node ids + const int* node_ids() const; + + // Returns node index of current calling thread. + uint index_of_current_thread() const; + + // Returns the preferred index for the given HeapRegion index. + // This assumes that HeapRegions are evenly spit, so we can decide preferred index + // with the given HeapRegion index. + // Result is less than num_active_nodes(). + uint preferred_node_index_for_index(uint region_index) const; + + // 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; + + // If AlwaysPreTouch is enabled, return actual node index via system call. + // If disabled, return preferred node index of the given heap region. + uint index_for_region(HeapRegion* hr) const; + + // 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. + uint max_search_depth() const; +}; + +#endif // SHARE_VM_GC_G1_NUMA_HPP