< prev index next >

src/hotspot/share/gc/g1/heapRegionSet.inline.hpp

Print this page
rev 56323 : imported patch 8220310.mut.0
rev 56324 : imported patch 8220310.mut.1_thomas
rev 56326 : [mq]: 8220310.mut.1-3_kim

@@ -23,10 +23,11 @@
  */
 
 #ifndef SHARE_GC_G1_HEAPREGIONSET_INLINE_HPP
 #define SHARE_GC_G1_HEAPREGIONSET_INLINE_HPP
 
+#include "gc/g1/g1NUMA.inline.hpp"
 #include "gc/g1/heapRegionSet.hpp"
 
 inline void HeapRegionSetBase::add(HeapRegion* hr) {
   check_mt_safety();
   assert_heap_region_set(hr->containing_set() == NULL, "should not already have a containing set");

@@ -145,6 +146,74 @@
   // remove() will verify the region and check mt safety.
   remove(hr);
   return hr;
 }
 
+inline HeapRegion* FreeRegionList::remove_region_with_node_index(bool from_head,
+                                                                 const uint requested_node_index,
+                                                                 uint* allocated_node_index) {
+  assert(UseNUMA, "Invariant");
+
+  HeapRegion * cur;
+  G1NUMA* numa = G1NUMA::numa();
+
+  if (!numa->is_valid_numa_index(requested_node_index)) {
+    return NULL;
+  }
+
+  // Multiple of 3 is just random number to limit iterations.
+  uint const max_search_depth = 3 * numa->num_active_numa_ids();
+
+  // Find the region to use, searching from _head or _tail as requested.
+  size_t cur_depth = 0;
+  if (from_head) {
+    for (cur = _head;
+         cur != NULL && cur_depth < max_search_depth;
+         cur = cur->next(), ++cur_depth) {
+      if (requested_node_index == cur->node_index()) {
+        break;
+      }
+    }
+  } else {
+    for (cur = _tail;
+         cur != NULL && cur_depth < max_search_depth;
+         cur = cur->prev(), ++cur_depth) {
+      if (requested_node_index == cur->node_index()) {
+        break;
+      }
+    }
+  }
+
+  // Didn't find a region to use.
+  if (cur == NULL || cur_depth >= max_search_depth) {
+    return NULL;
+  }
+
+  // Splice the region out of the list.
+  HeapRegion* prev = cur->prev();
+  HeapRegion* next = cur->next();
+  if (prev == NULL) {
+    _head = next;
+  } else {
+    prev->set_next(next);
+  }
+  if (next == NULL) {
+    _tail = prev;
+  } else {
+    next->set_prev(prev);
+  }
+  cur->set_prev(NULL);
+  cur->set_next(NULL);
+
+  if (_last == cur) {
+    _last = NULL;
+  }
+
+  remove(cur);
+  if (allocated_node_index != NULL) {
+    *allocated_node_index = cur->node_index();
+  }
+
+  return cur;
+}
+
 #endif // SHARE_GC_G1_HEAPREGIONSET_INLINE_HPP
< prev index next >