< 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,37 ****
--- 28,38 ----
#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,110 ****
--- 102,145 ----
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,146 ****
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) {
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);
// Also commit auxiliary data
! _prev_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
! _next_bitmap_mapper->commit_regions(index, num_regions, pretouch_gang);
! _bot_mapper->commit_regions(index, num_regions, pretouch_gang);
! _cardtable_mapper->commit_regions(index, num_regions, pretouch_gang);
! _card_counts_mapper->commit_regions(index, num_regions, 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");
// 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);
--- 150,186 ----
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, 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, node_index, pretouch_gang);
// Also commit auxiliary data
! _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, node_index, pretouch_gang);
! _cardtable_mapper->commit_regions(index, num_regions, node_index, 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,172 ****
_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) {
guarantee(num_regions > 0, "No point in calling this for zero regions");
! commit_regions(start, num_regions, 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);
--- 200,229 ----
_cardtable_mapper->uncommit_regions(start, num_regions);
_card_counts_mapper->uncommit_regions(start, num_regions);
}
! 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, 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,194 ****
--- 242,257 ----
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,220 ****
_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_at(uint start, uint num_regions, WorkGang* pretouch_workers) {
if (num_regions == 0) {
return 0;
}
uint cur = start;
--- 269,283 ----
_card_counts_mapper->reserved_size();
return MemoryUsage(0, used_sz, committed_sz, committed_sz);
}
! 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, uint node_index, WorkGang* pretouch_workers) {
if (num_regions == 0) {
return 0;
}
uint cur = start;
*** 224,234 ****
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);
expanded += to_expand;
cur = idx_last_found + num_last_found + 1;
}
verify_optional();
--- 287,297 ----
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, node_index, pretouch_workers);
expanded += to_expand;
cur = idx_last_found + num_last_found + 1;
}
verify_optional();
*** 329,339 ****
// 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);
if (res == 1) {
*expanded = true;
return curr;
}
} else {
--- 392,402 ----
// 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, G1MemoryNodeManager::AnyNodeIndex, NULL);
if (res == 1) {
*expanded = true;
return curr;
}
} else {
*** 357,367 ****
// 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);
}
HeapRegion* curr_region = _regions.get_by_index(curr_index);
if (!curr_region->is_free()) {
return false;
}
--- 420,430 ----
// 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, G1MemoryNodeManager::AnyNodeIndex, pretouch_workers);
}
HeapRegion* curr_region = _regions.get_by_index(curr_index);
if (!curr_region->is_free()) {
return false;
}
< prev index next >