--- old/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2019-09-30 17:13:03.556029664 -0700 +++ new/src/hotspot/share/gc/g1/g1CollectedHeap.cpp 2019-09-30 17:13:03.184029677 -0700 @@ -169,12 +169,15 @@ // Private methods. -HeapRegion* G1CollectedHeap::new_region(size_t word_size, HeapRegionType type, bool do_expand) { +HeapRegion* G1CollectedHeap::new_region(size_t word_size, + HeapRegionType type, + bool do_expand, + uint node_index) { assert(!is_humongous(word_size) || word_size <= HeapRegion::GrainWords, "the only time we use this to allocate a humongous region is " "when we are allocating a single humongous region"); - HeapRegion* res = _hrm->allocate_free_region(type); + HeapRegion* res = _hrm->allocate_free_region(type, node_index); if (res == NULL && do_expand && _expand_heap_after_alloc_failure) { // Currently, only attempts to allocate GC alloc regions set @@ -186,12 +189,15 @@ log_debug(gc, ergo, heap)("Attempt heap expansion (region allocation request failed). Allocation request: " SIZE_FORMAT "B", word_size * HeapWordSize); - if (expand(word_size * HeapWordSize)) { - // Given that expand() succeeded in expanding the heap, and we + assert(word_size * HeapWordSize < HeapRegion::GrainBytes, + "This kind of expansion should never be more than one region. Size: " SIZE_FORMAT, + word_size * HeapWordSize); + if (expand_single_region(node_index)) { + // Given that expand_single_region() succeeded in expanding the heap, and we // always expand the heap by an amount aligned to the heap // region size, the free list should in theory not be empty. // In either case allocate_free_region() will check for NULL. - res = _hrm->allocate_free_region(type); + res = _hrm->allocate_free_region(type, node_index); } else { _expand_heap_after_alloc_failure = false; } @@ -1022,7 +1028,7 @@ void G1CollectedHeap::prepare_heap_for_full_collection() { // Make sure we'll choose a new allocation region afterwards. - _allocator->release_mutator_alloc_region(); + _allocator->release_mutator_alloc_regions(); _allocator->abandon_gc_alloc_regions(); // We may have added regions to the current incremental collection @@ -1066,7 +1072,7 @@ // Start a new incremental collection set for the next pause start_new_collection_set(); - _allocator->init_mutator_alloc_region(); + _allocator->init_mutator_alloc_regions(); // Post collection state updates. MetaspaceGC::compute_new_size(); @@ -1383,6 +1389,21 @@ return regions_to_expand > 0; } +bool G1CollectedHeap::expand_single_region(uint node_index) { + log_debug(gc, ergo, heap)("Expand the heap by a single region"); + + uint expanded_by = _hrm->expand_on_preferred_node(node_index); + + if (expanded_by == 0) { + assert(is_maximal_no_gc(), "Should be no regions left, available: %u", _hrm->available()); + log_debug(gc, ergo, heap)("Did not expand the heap (heap already fully expanded)"); + return false; + } + + policy()->record_new_heap_size(num_regions()); + return true; +} + void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { size_t aligned_shrink_bytes = ReservedSpace::page_align_size_down(shrink_bytes); @@ -1393,7 +1414,6 @@ uint num_regions_removed = _hrm->shrink_by(num_regions_to_remove); size_t shrunk_bytes = num_regions_removed * HeapRegion::GrainBytes; - log_debug(gc, ergo, heap)("Shrink the heap. requested shrinking amount: " SIZE_FORMAT "B aligned shrinking amount: " SIZE_FORMAT "B attempted shrinking amount: " SIZE_FORMAT "B", shrink_bytes, aligned_shrink_bytes, shrunk_bytes); if (num_regions_removed > 0) { @@ -1495,6 +1515,7 @@ _humongous_set("Humongous Region Set", new HumongousRegionSetChecker()), _bot(NULL), _listener(), + _mem_node_mgr(G1MemoryNodeManager::create()), _hrm(NULL), _allocator(NULL), _verifier(NULL), @@ -1778,6 +1799,8 @@ } _workers->initialize_workers(); + _mem_node_mgr->set_page_size(page_size); + // Create the G1ConcurrentMark data structure and thread. // (Must do this late, so that "max_regions" is defined.) _cm = new G1ConcurrentMark(this, prev_bitmap_storage, next_bitmap_storage); @@ -1825,7 +1848,7 @@ dummy_region->set_top(dummy_region->end()); G1AllocRegion::setup(this, dummy_region); - _allocator->init_mutator_alloc_region(); + _allocator->init_mutator_alloc_regions(); // Do create of the monitoring and management support so that // values in the heap have been properly initialized. @@ -3008,7 +3031,7 @@ // Forget the current allocation region (we might even choose it to be part // of the collection set!). - _allocator->release_mutator_alloc_region(); + _allocator->release_mutator_alloc_regions(); calculate_collection_set(evacuation_info, target_pause_time_ms); @@ -3045,7 +3068,7 @@ allocate_dummy_regions(); - _allocator->init_mutator_alloc_region(); + _allocator->init_mutator_alloc_regions(); expand_heap_after_young_collection(); @@ -4548,13 +4571,15 @@ // Methods for the mutator alloc region HeapRegion* G1CollectedHeap::new_mutator_alloc_region(size_t word_size, - bool force) { + bool force, + uint node_index) { assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); bool should_allocate = policy()->should_allocate_mutator_region(); if (force || should_allocate) { HeapRegion* new_alloc_region = new_region(word_size, HeapRegionType::Eden, - false /* do_expand */); + false /* do_expand */, + node_index); if (new_alloc_region != NULL) { set_region_short_lived_locked(new_alloc_region); _hr_printer.alloc(new_alloc_region, !should_allocate);