# HG changeset patch # User sjohanss # Date 1410213925 -7200 # Node ID d35872270666777ec6bea7916edf1f64435a3efd # Parent 99f0593d8c9fff6579d0b5e927f27cf9facefd3b 8057658: Enable G1 FullGC extensions Summary: Refactored the G1 FullGC code to enable it to be extended. Reviewed-by: mgerdin, brutisso diff -r 99f0593d8c9f -r d35872270666 src/share/vm/gc_implementation/g1/g1Allocator.hpp --- a/src/share/vm/gc_implementation/g1/g1Allocator.hpp Mon Sep 08 14:13:01 2014 +0000 +++ b/src/share/vm/gc_implementation/g1/g1Allocator.hpp Tue Sep 09 00:05:25 2014 +0200 @@ -86,6 +86,12 @@ void set_used(size_t bytes) { _summary_bytes_used = bytes; } + + virtual HeapRegion* new_heap_region(uint hrs_index, + G1BlockOffsetSharedArray* sharedOffsetArray, + MemRegion mr) { + return new HeapRegion(hrs_index, sharedOffsetArray, mr); + } }; // The default allocator for G1. diff -r 99f0593d8c9f -r d35872270666 src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Mon Sep 08 14:13:01 2014 +0000 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Sep 09 00:05:25 2014 +0200 @@ -620,6 +620,10 @@ public: + G1Allocator* allocator() { + return _allocator; + } + G1MonitoringSupport* g1mm() { assert(_g1mm != NULL, "should have been initialized"); return _g1mm; diff -r 99f0593d8c9f -r d35872270666 src/share/vm/gc_implementation/g1/g1MarkSweep.cpp --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Mon Sep 08 14:13:01 2014 +0000 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Tue Sep 09 00:05:25 2014 +0200 @@ -194,76 +194,6 @@ gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive); } -class G1PrepareCompactClosure: public HeapRegionClosure { - G1CollectedHeap* _g1h; - ModRefBarrierSet* _mrbs; - CompactPoint _cp; - HeapRegionSetCount _humongous_regions_removed; - - bool is_cp_initialized() const { - return _cp.space != NULL; - } - - void prepare_for_compaction(HeapRegion* hr, HeapWord* end) { - // If this is the first live region that we came across which we can compact, - // initialize the CompactPoint. - if (!is_cp_initialized()) { - _cp.space = hr; - _cp.threshold = hr->initialize_threshold(); - } - hr->prepare_for_compaction(&_cp); - // Also clear the part of the card table that will be unused after - // compaction. - _mrbs->clear(MemRegion(hr->compaction_top(), end)); - } - - void free_humongous_region(HeapRegion* hr) { - HeapWord* end = hr->end(); - FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep"); - - assert(hr->startsHumongous(), - "Only the start of a humongous region should be freed."); - - hr->set_containing_set(NULL); - _humongous_regions_removed.increment(1u, hr->capacity()); - - _g1h->free_humongous_region(hr, &dummy_free_list, false /* par */); - prepare_for_compaction(hr, end); - dummy_free_list.remove_all(); - } - -public: - G1PrepareCompactClosure() - : _g1h(G1CollectedHeap::heap()), - _mrbs(_g1h->g1_barrier_set()), - _cp(NULL), - _humongous_regions_removed() { } - - void update_sets() { - // We'll recalculate total used bytes and recreate the free list - // at the end of the GC, so no point in updating those values here. - HeapRegionSetCount empty_set; - _g1h->remove_from_old_sets(empty_set, _humongous_regions_removed); - } - - bool doHeapRegion(HeapRegion* hr) { - if (hr->isHumongous()) { - if (hr->startsHumongous()) { - oop obj = oop(hr->bottom()); - if (obj->is_gc_marked()) { - obj->forward_to(obj); - } else { - free_humongous_region(hr); - } - } else { - assert(hr->continuesHumongous(), "Invalid humongous."); - } - } else { - prepare_for_compaction(hr, hr->end()); - } - return false; - } -}; void G1MarkSweep::mark_sweep_phase2() { // Now all live objects are marked, compute the new object addresses. @@ -272,14 +202,10 @@ // phase2, phase3 and phase4, but the ValidateMarkSweep live oops // tracking expects us to do so. See comment under phase4. - G1CollectedHeap* g1h = G1CollectedHeap::heap(); - GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id()); GenMarkSweep::trace("2"); - G1PrepareCompactClosure blk; - g1h->heap_region_iterate(&blk); - blk.update_sets(); + prepare_compaction(); } class G1AdjustPointersClosure: public HeapRegionClosure { @@ -374,3 +300,68 @@ g1h->heap_region_iterate(&blk); } + +void G1MarkSweep::prepare_compaction_work(G1PrepareCompactClosure* blk) { + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + g1h->heap_region_iterate(blk); + blk->update_sets(); +} + +void G1PrepareCompactClosure::free_humongous_region(HeapRegion* hr) { + HeapWord* end = hr->end(); + FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep"); + + assert(hr->startsHumongous(), + "Only the start of a humongous region should be freed."); + + hr->set_containing_set(NULL); + _humongous_regions_removed.increment(1u, hr->capacity()); + + _g1h->free_humongous_region(hr, &dummy_free_list, false /* par */); + prepare_for_compaction(hr, end); + dummy_free_list.remove_all(); +} + +void G1PrepareCompactClosure::prepare_for_compaction(HeapRegion* hr, HeapWord* end) { + // If this is the first live region that we came across which we can compact, + // initialize the CompactPoint. + if (!is_cp_initialized()) { + _cp.space = hr; + _cp.threshold = hr->initialize_threshold(); + } + prepare_for_compaction_work(&_cp, hr, end); +} + +void G1PrepareCompactClosure::prepare_for_compaction_work(CompactPoint* cp, + HeapRegion* hr, + HeapWord* end) { + hr->prepare_for_compaction(cp); + // Also clear the part of the card table that will be unused after + // compaction. + _mrbs->clear(MemRegion(hr->compaction_top(), end)); +} + +void G1PrepareCompactClosure::update_sets() { + // We'll recalculate total used bytes and recreate the free list + // at the end of the GC, so no point in updating those values here. + HeapRegionSetCount empty_set; + _g1h->remove_from_old_sets(empty_set, _humongous_regions_removed); +} + +bool G1PrepareCompactClosure::doHeapRegion(HeapRegion* hr) { + if (hr->isHumongous()) { + if (hr->startsHumongous()) { + oop obj = oop(hr->bottom()); + if (obj->is_gc_marked()) { + obj->forward_to(obj); + } else { + free_humongous_region(hr); + } + } else { + assert(hr->continuesHumongous(), "Invalid humongous."); + } + } else { + prepare_for_compaction(hr, hr->end()); + } + return false; +} diff -r 99f0593d8c9f -r d35872270666 src/share/vm/gc_implementation/g1/g1MarkSweep.hpp --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp Mon Sep 08 14:13:01 2014 +0000 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp Tue Sep 09 00:05:25 2014 +0200 @@ -43,7 +43,7 @@ // compaction. // // Class unloading will only occur when a full gc is invoked. - +class G1PrepareCompactClosure; class G1MarkSweep : AllStatic { friend class VM_G1MarkSweep; @@ -70,6 +70,30 @@ static void mark_sweep_phase4(); static void allocate_stacks(); + static void prepare_compaction(); + static void prepare_compaction_work(G1PrepareCompactClosure* blk); +}; + +class G1PrepareCompactClosure : public HeapRegionClosure { + protected: + G1CollectedHeap* _g1h; + ModRefBarrierSet* _mrbs; + CompactPoint _cp; + HeapRegionSetCount _humongous_regions_removed; + + virtual void prepare_for_compaction(HeapRegion* hr, HeapWord* end); + void prepare_for_compaction_work(CompactPoint* cp, HeapRegion* hr, HeapWord* end); + void free_humongous_region(HeapRegion* hr); + bool is_cp_initialized() const { return _cp.space != NULL; } + + public: + G1PrepareCompactClosure() : + _g1h(G1CollectedHeap::heap()), + _mrbs(_g1h->g1_barrier_set()), + _humongous_regions_removed() { } + + void update_sets(); + bool doHeapRegion(HeapRegion* hr); }; #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1MARKSWEEP_HPP diff -r 99f0593d8c9f -r d35872270666 src/share/vm/gc_implementation/g1/g1MarkSweep_ext.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep_ext.cpp Tue Sep 09 00:05:25 2014 +0200 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/g1/g1MarkSweep.hpp" + +void G1MarkSweep::prepare_compaction() { + G1PrepareCompactClosure blk; + G1MarkSweep::prepare_compaction_work(&blk); +} diff -r 99f0593d8c9f -r d35872270666 src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp Mon Sep 08 14:13:01 2014 +0000 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp Tue Sep 09 00:05:25 2014 +0200 @@ -347,9 +347,10 @@ HeapRegion::HeapRegion(uint hrm_index, G1BlockOffsetSharedArray* sharedOffsetArray, - MemRegion mr, AllocationContext_t context) : + MemRegion mr) : G1OffsetTableContigSpace(sharedOffsetArray, mr), - _hrm_index(hrm_index), _allocation_context(context), + _hrm_index(hrm_index), + _allocation_context(AllocationContext::system()), _humongous_type(NotHumongous), _humongous_start_region(NULL), _in_collection_set(false), _next_in_special_set(NULL), _orig_end(NULL), diff -r 99f0593d8c9f -r d35872270666 src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/src/share/vm/gc_implementation/g1/heapRegion.hpp Mon Sep 08 14:13:01 2014 +0000 +++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp Tue Sep 09 00:05:25 2014 +0200 @@ -335,8 +335,7 @@ public: HeapRegion(uint hrm_index, G1BlockOffsetSharedArray* sharedOffsetArray, - MemRegion mr, - AllocationContext_t context = AllocationContext::system()); + MemRegion mr); // Initializing the HeapRegion not only resets the data structure, but also // resets the BOT for that heap region. diff -r 99f0593d8c9f -r d35872270666 src/share/vm/gc_implementation/g1/heapRegionManager.cpp --- a/src/share/vm/gc_implementation/g1/heapRegionManager.cpp Mon Sep 08 14:13:01 2014 +0000 +++ b/src/share/vm/gc_implementation/g1/heapRegionManager.cpp Tue Sep 09 00:05:25 2014 +0200 @@ -66,10 +66,11 @@ #endif HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) { - HeapWord* bottom = G1CollectedHeap::heap()->bottom_addr_for_region(hrm_index); + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + HeapWord* bottom = g1h->bottom_addr_for_region(hrm_index); MemRegion mr(bottom, bottom + HeapRegion::GrainWords); assert(reserved().contains(mr), "invariant"); - return new HeapRegion(hrm_index, G1CollectedHeap::heap()->bot_shared(), mr); + return g1h->allocator()->new_heap_region(hrm_index, g1h->bot_shared(), mr); } void HeapRegionManager::commit_regions(uint index, size_t num_regions) { diff -r 99f0593d8c9f -r d35872270666 src/share/vm/memory/space.hpp --- a/src/share/vm/memory/space.hpp Mon Sep 08 14:13:01 2014 +0000 +++ b/src/share/vm/memory/space.hpp Tue Sep 09 00:05:25 2014 +0200 @@ -331,11 +331,10 @@ CompactibleSpace* space; HeapWord* threshold; - CompactPoint(Generation* _gen) : - gen(_gen), space(NULL), threshold(0) {} + CompactPoint(Generation* g = NULL) : + gen(g), space(NULL), threshold(0) {} }; - // A space that supports compaction operations. This is usually, but not // necessarily, a space that is normally contiguous. But, for example, a // free-list-based space whose normal collection is a mark-sweep without