< prev index next >

src/hotspot/share/gc/g1/g1NUMA.cpp

Print this page

        

@@ -22,12 +22,11 @@
  *
  */
 
 #include "precompiled.hpp"
 #include "gc/g1/g1NUMA.hpp"
-#include "gc/g1/heapRegion.hpp"
-#include "logging/log.hpp"
+#include "logging/logStream.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 
 G1NUMA* G1NUMA::_inst = NULL;
 

@@ -72,11 +71,11 @@
 }
 
 G1NUMA::G1NUMA() :
   _node_id_to_index_map(NULL), _len_node_id_to_index_map(0),
   _node_ids(NULL), _num_active_node_ids(0),
-  _region_size(0), _page_size(0) {
+  _region_size(0), _page_size(0), _stats(NULL) {
 }
 
 void G1NUMA::initialize_without_numa() {
   // If NUMA is not enabled or supported, initialize as having a singel node.
   _num_active_node_ids = 1;

@@ -117,13 +116,16 @@
 
   // Set the indices for the actually retrieved node ids.
   for (uint i = 0; i < _num_active_node_ids; i++) {
     _node_id_to_index_map[_node_ids[i]] = i;
   }
+
+  _stats = new G1NUMAStats(_node_ids, _num_active_node_ids);
 }
 
 G1NUMA::~G1NUMA() {
+  delete _stats;
   FREE_C_HEAP_ARRAY(int, _node_id_to_index_map);
   FREE_C_HEAP_ARRAY(int, _node_ids);
 }
 
 void G1NUMA::set_region_info(size_t region_size, size_t page_size) {

@@ -213,15 +215,92 @@
   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).",
+  log_trace(gc, heap, numa)("Request memory [" PTR_FORMAT ", " PTR_FORMAT ") to be NUMA id (%d)",
                             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.
   return 3 * MAX2((uint)(page_size() / region_size()), (uint)1) * num_active_nodes();
 }
+
+void G1NUMA::update_statistics(G1NUMAStats::NodeDataItems phase,
+                               uint requested_node_index,
+                               uint allocated_node_index) {
+  if (_stats == NULL) {
+    return;
+  }
+
+  uint converted_req_index;
+  if(requested_node_index < _num_active_node_ids) {
+    converted_req_index = requested_node_index;
+  } else {
+    assert(requested_node_index == AnyNodeIndex,
+           "Requested node index %u should be AnyNodeIndex.", requested_node_index);
+    converted_req_index = _num_active_node_ids;
+  }
+  _stats->update(phase, converted_req_index, allocated_node_index);
+}
+
+void G1NUMA::copy_statistics(G1NUMAStats::NodeDataItems phase, 
+                             uint requested_node_index,
+                             size_t* allocated_stat) {
+  if (_stats == NULL) {
+    return;
+  }
+
+  _stats->copy(phase, requested_node_index, allocated_stat);
+}
+
+void G1NUMA::print_statistics() const {
+  if (_stats == NULL) {
+    return;
+  }
+
+  _stats->print_statistics();
+}
+
+NodeIndexCheckClosure::NodeIndexCheckClosure(const char* desc, G1NUMA* numa, LogStream* ls) :
+  _desc(desc), _numa(numa), _ls(ls) {
+
+  uint num_nodes = _numa->num_active_nodes();
+  _matched = NEW_C_HEAP_ARRAY(uint, num_nodes, mtGC);
+  _mismatched = NEW_C_HEAP_ARRAY(uint, num_nodes, mtGC);
+  _total = NEW_C_HEAP_ARRAY(uint, num_nodes, mtGC);
+  memset(_matched, 0, sizeof(uint) * num_nodes);
+  memset(_mismatched, 0, sizeof(uint) * num_nodes);
+  memset(_total, 0, sizeof(uint) * num_nodes);
+}
+
+NodeIndexCheckClosure::~NodeIndexCheckClosure() {
+  _ls->print("%s: NUMA region verification (id: matched/mismatched/total): ", _desc);
+  const int* numa_ids = _numa->node_ids();
+  for (uint i = 0; i < _numa->num_active_nodes(); i++) {
+    _ls->print("%d: %u/%u/%u ", numa_ids[i], _matched[i], _mismatched[i], _total[i]);
+  }
+
+  FREE_C_HEAP_ARRAY(uint, _matched);
+  FREE_C_HEAP_ARRAY(uint, _mismatched);
+  FREE_C_HEAP_ARRAY(uint, _total);
+}
+
+bool NodeIndexCheckClosure::do_heap_region(HeapRegion* hr) {
+  // Preferred node index will only have valid node index.
+  uint preferred_node_index = _numa->preferred_node_index_for_index(hr->hrm_index());
+  // Active node index may have UnknownNodeIndex.
+  uint active_node_index = _numa->index_of_address(hr->bottom());
+
+  if (preferred_node_index == active_node_index) {
+    _matched[preferred_node_index]++;
+  } else if (preferred_node_index != active_node_index &&
+             active_node_index != G1NUMA::UnknownNodeIndex) {
+    _mismatched[preferred_node_index]++;
+  }
+  _total[preferred_node_index]++;
+
+  return false;
+}
< prev index next >