< prev index next >
src/hotspot/share/gc/g1/heapRegionManager.cpp
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
@@ -28,10 +28,11 @@
#include "gc/g1/g1ConcurrentRefine.hpp"
#include "gc/g1/heapRegion.hpp"
#include "gc/g1/heapRegionManager.inline.hpp"
#include "gc/g1/heapRegionSet.inline.hpp"
#include "gc/g1/heterogeneousHeapRegionManager.hpp"
+#include "logging/logStream.hpp"
#include "memory/allocation.hpp"
#include "utilities/bitMap.inline.hpp"
class MasterFreeRegionListChecker : public HeapRegionSetChecker {
public:
@@ -101,10 +102,44 @@
bool HeapRegionManager::is_available(uint region) const {
return _available_map.at(region);
}
+HeapRegion* HeapRegionManager::allocate_free_region(HeapRegionType type, uint requested_node_index) {
+ G1MemoryNodeManager* mgr = G1MemoryNodeManager::mgr();
+ HeapRegion* hr = NULL;
+ bool from_head = !type.is_young();
+
+ if (mgr->num_active_nodes() > 1) {
+ uint valid_node_index = mgr->valid_node_index(requested_node_index);
+ // Try to allocate with requested node index.
+ hr = _free_list.remove_region_with_node_index(from_head, valid_node_index, NULL);
+ }
+
+ if (hr == NULL) {
+ // If there's a single active node or we did not get a region from our requested node,
+ // try without requested node index.
+ hr = _free_list.remove_region(from_head);
+ }
+
+ if (hr != NULL) {
+ assert(hr->next() == NULL, "Single region should not have next");
+ assert(is_available(hr->hrm_index()), "Must be committed");
+ if (G1VerifyNUMAIdOfHeapRegions) {
+ // Read actual node index via system call.
+ uint actual_node_index = mgr->index_of_address(hr->bottom());
+ if (hr->node_index() != actual_node_index) {
+ log_debug(gc, heap, numa)("Heap Region (%u) has different node index. "
+ "actual index=%u, index=%u",
+ hr->hrm_index(), actual_node_index, hr->node_index());
+ }
+ }
+ }
+
+ return hr;
+}
+
#ifdef ASSERT
bool HeapRegionManager::is_free(HeapRegion* hr) const {
return _free_list.contains(hr);
}
#endif
@@ -115,32 +150,37 @@
MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
assert(reserved().contains(mr), "invariant");
return g1h->new_heap_region(hrm_index, mr);
}
-void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang) {
+void HeapRegionManager::commit_regions(uint index, size_t num_regions, uint node_index, WorkGang* pretouch_gang) {
guarantee(num_regions > 0, "Must commit more than zero regions");
guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
_num_committed += (uint)num_regions;
- _heap_mapper->commit_regions(index, num_regions, pretouch_gang);
+ _heap_mapper->commit_regions(index, num_regions, node_index, pretouch_gang);
// Also commit auxiliary data
- _prev_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
- _next_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
+ _prev_bitmap_mapper->commit_regions(index, num_regions, node_index, pretouch_gang);
+ _next_bitmap_mapper->commit_regions(index, num_regions, node_index, pretouch_gang);
- _bot_mapper->commit_regions(index, num_regions, pretouch_gang);
- _cardtable_mapper->commit_regions(index, num_regions, pretouch_gang);
+ _bot_mapper->commit_regions(index, num_regions, node_index, pretouch_gang);
+ _cardtable_mapper->commit_regions(index, num_regions, node_index, pretouch_gang);
- _card_counts_mapper->commit_regions(index, num_regions, pretouch_gang);
+ _card_counts_mapper->commit_regions(index, num_regions, node_index, pretouch_gang);
}
void HeapRegionManager::uncommit_regions(uint start, size_t num_regions) {
guarantee(num_regions >= 1, "Need to specify at least one region to uncommit, tried to uncommit zero regions at %u", start);
guarantee(_num_committed >= num_regions, "pre-condition");
+ // Reset node index to distinguish with committed regions.
+ for (uint i = start; i < start + num_regions; i++) {
+ at(i)->set_node_index(G1MemoryNodeManager::InvalidNodeIndex);
+ }
+
// Print before uncommitting.
if (G1CollectedHeap::heap()->hr_printer()->is_active()) {
for (uint i = start; i < start + num_regions; i++) {
HeapRegion* hr = at(i);
G1CollectedHeap::heap()->hr_printer()->uncommit(hr);
@@ -160,13 +200,30 @@
_cardtable_mapper->uncommit_regions(start, num_regions);
_card_counts_mapper->uncommit_regions(start, num_regions);
}
-void HeapRegionManager::make_regions_available(uint start, uint num_regions, WorkGang* pretouch_gang) {
+static void print_numa_id_of_regions(uint start, uint num_regions) {
+ LogTarget(Debug, gc, heap, numa) lt;
+
+ if (lt.is_enabled()) {
+ LogStream ls(lt);
+
+ // Print header
+ // Below logs are checked by TestG1NUMATouchRegions.java.
+ ls.print_cr("Numa id of heap regions from %u to %u", start, start + num_regions - 1);
+ ls.print_cr("Heap Region# : numa id of pages");
+
+ for (uint i = start; i < start + num_regions; i++) {
+ ls.print_cr("%6u : %u", i, G1CollectedHeap::heap()->region_at(i)->node_index());
+ }
+ }
+}
+
+void HeapRegionManager::make_regions_available(uint start, uint num_regions, uint node_index, WorkGang* pretouch_gang) {
guarantee(num_regions > 0, "No point in calling this for zero regions");
- commit_regions(start, num_regions, pretouch_gang);
+ commit_regions(start, num_regions, node_index, pretouch_gang);
for (uint i = start; i < start + num_regions; i++) {
if (_regions.get_by_index(i) == NULL) {
HeapRegion* new_hr = new_heap_region(i);
OrderAccess::storestore();
_regions.set_by_index(i, new_hr);
@@ -185,10 +242,16 @@
HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(i);
MemRegion mr(bottom, bottom + HeapRegion::GrainWords);
hr->initialize(mr);
insert_into_free_list(at(i));
+ // Set node index of the heap region after initialization.
+ hr->set_node_index(G1MemoryNodeManager::mgr()->index_of_address(bottom));
+ }
+
+ if (G1PrintNUMAIdOfHeapRegions) {
+ print_numa_id_of_regions(start, num_regions);
}
}
MemoryUsage HeapRegionManager::get_auxiliary_data_memory_usage() const {
size_t used_sz =
@@ -206,15 +269,15 @@
_card_counts_mapper->reserved_size();
return MemoryUsage(0, used_sz, committed_sz, committed_sz);
}
-uint HeapRegionManager::expand_by(uint num_regions, WorkGang* pretouch_workers) {
- return expand_at(0, num_regions, pretouch_workers);
+uint HeapRegionManager::expand_by(uint num_regions, uint node_index, WorkGang* pretouch_workers) {
+ return expand_at(0, num_regions, node_index, pretouch_workers);
}
-uint HeapRegionManager::expand_at(uint start, uint num_regions, WorkGang* pretouch_workers) {
+uint HeapRegionManager::expand_at(uint start, uint num_regions, uint node_index, WorkGang* pretouch_workers) {
if (num_regions == 0) {
return 0;
}
uint cur = start;
@@ -224,11 +287,11 @@
uint expanded = 0;
while (expanded < num_regions &&
(num_last_found = find_unavailable_from_idx(cur, &idx_last_found)) > 0) {
uint to_expand = MIN2(num_regions - expanded, num_last_found);
- make_regions_available(idx_last_found, to_expand, pretouch_workers);
+ make_regions_available(idx_last_found, to_expand, node_index, pretouch_workers);
expanded += to_expand;
cur = idx_last_found + num_last_found + 1;
}
verify_optional();
@@ -329,11 +392,11 @@
// committed, expand_at that index.
uint curr = max_length() - 1;
while (true) {
HeapRegion *hr = _regions.get_by_index(curr);
if (hr == NULL || !is_available(curr)) {
- uint res = expand_at(curr, 1, NULL);
+ uint res = expand_at(curr, 1, G1MemoryNodeManager::AnyNodeIndex, NULL);
if (res == 1) {
*expanded = true;
return curr;
}
} else {
@@ -357,11 +420,11 @@
// Ensure that each G1 region in the range is free, returning false if not.
// Commit those that are not yet available, and keep count.
for (uint curr_index = start_index; curr_index <= last_index; curr_index++) {
if (!is_available(curr_index)) {
commits++;
- expand_at(curr_index, 1, pretouch_workers);
+ expand_at(curr_index, 1, G1MemoryNodeManager::AnyNodeIndex, pretouch_workers);
}
HeapRegion* curr_region = _regions.get_by_index(curr_index);
if (!curr_region->is_free()) {
return false;
}
< prev index next >