# HG changeset patch # User rkennke # Date 1531860253 -7200 # Tue Jul 17 22:44:13 2018 +0200 # Node ID b68562c62ddf0512a6764f468307c5b3a2e67d75 # Parent e9cb9f7ae84355fdaae1e69018208891d515ff66 Refactor to group marking bitmap and TAMS structure in one class ShenandoahMarkingContext diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp @@ -29,6 +29,7 @@ #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahTraversalGC.hpp" #include "memory/resourceArea.hpp" @@ -62,10 +63,10 @@ r->print_on(&ss); msg.append(" " PTR_FORMAT " - klass " PTR_FORMAT " %s\n", p2i(obj), p2i(obj->klass()), obj->klass()->external_name()); - msg.append(" %3s allocated after complete mark start\n", heap->allocated_after_complete_mark_start((HeapWord *) obj) ? "" : "not"); - msg.append(" %3s allocated after next mark start\n", heap->allocated_after_next_mark_start((HeapWord *) obj) ? "" : "not"); - msg.append(" %3s marked complete\n", heap->is_marked_complete(obj) ? "" : "not"); - msg.append(" %3s marked next\n", heap->is_marked_next(obj) ? "" : "not"); + msg.append(" %3s allocated after complete mark start\n", heap->complete_marking_context()->allocated_after_mark_start((HeapWord *) obj) ? "" : "not"); + msg.append(" %3s allocated after next mark start\n", heap->next_marking_context()->allocated_after_mark_start((HeapWord *) obj) ? "" : "not"); + msg.append(" %3s marked complete\n", heap->complete_marking_context()->is_marked(obj) ? "" : "not"); + msg.append(" %3s marked next\n", heap->next_marking_context()->is_marked(obj) ? "" : "not"); msg.append(" %3s in collection set\n", heap->in_collection_set(obj) ? "" : "not"); if (heap->traversal_gc() != NULL) { msg.append(" %3s in root set\n", heap->traversal_gc()->root_regions()->is_in((HeapWord*) obj) ? "" : "not"); @@ -320,7 +321,7 @@ assert_correct(interior_loc, obj, file, line); ShenandoahHeap* heap = ShenandoahHeap::heap_no_check(); - if (!heap->is_marked_complete(obj)) { + if (!heap->complete_marking_context()->is_marked(obj)) { print_failure(_safe_all, obj, interior_loc, NULL, "Shenandoah assert_marked_complete failed", "Object should be marked (complete)", file, line); @@ -331,7 +332,7 @@ assert_correct(interior_loc, obj, file, line); ShenandoahHeap* heap = ShenandoahHeap::heap_no_check(); - if (!heap->is_marked_next(obj)) { + if (!heap->next_marking_context()->is_marked(obj)) { print_failure(_safe_all, obj, interior_loc, NULL, "Shenandoah assert_marked_next failed", "Object should be marked (next)", file, line); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.inline.hpp @@ -29,6 +29,7 @@ #include "gc/shenandoah/shenandoahAsserts.hpp" #include "gc/shenandoah/shenandoahBarrierSet.inline.hpp" #include "gc/shenandoah/shenandoahConcurrentMark.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahStringDedup.hpp" #include "memory/iterator.inline.hpp" #include "oops/oop.inline.hpp" @@ -265,7 +266,7 @@ shenandoah_assert_not_forwarded(p, obj); shenandoah_assert_not_in_cset_except(p, obj, heap->cancelled_gc()); - if (heap->mark_next(obj)) { + if (heap->next_marking_context()->mark(obj)) { bool pushed = q->push(ShenandoahMarkTask(obj)); assert(pushed, "overflow queue should always succeed pushing"); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp @@ -26,6 +26,7 @@ #include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahTraversalGC.hpp" ShenandoahFreeSet::ShenandoahFreeSet(ShenandoahHeap* heap, size_t max_regions) : @@ -198,7 +199,7 @@ // Traversal needs to traverse through GC allocs. Adjust TAMS to the new top // so that these allocations appear below TAMS, and thus get traversed. // See top of shenandoahTraversal.cpp for an explanation. - _heap->set_next_top_at_mark_start(r->bottom(), r->top()); + _heap->next_marking_context()->set_top_at_mark_start(r->region_number(), r->top()); _heap->traversal_gc()->traversal_set()->add_region_check_for_duplicates(r); OrderAccess::fence(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -44,6 +44,7 @@ #include "gc/shenandoah/shenandoahHeapRegion.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" #include "gc/shenandoah/shenandoahMarkCompact.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahMemoryPool.hpp" #include "gc/shenandoah/shenandoahMetrics.hpp" #include "gc/shenandoah/shenandoahMonitoringSupport.hpp" @@ -177,14 +178,6 @@ _collection_set = new ShenandoahCollectionSet(this, (HeapWord*)pgc_rs.base()); - _next_top_at_mark_starts_base = NEW_C_HEAP_ARRAY(HeapWord*, _num_regions, mtGC); - _next_top_at_mark_starts = _next_top_at_mark_starts_base - - ((uintx) pgc_rs.base() >> ShenandoahHeapRegion::region_size_bytes_shift()); - - _complete_top_at_mark_starts_base = NEW_C_HEAP_ARRAY(HeapWord*, _num_regions, mtGC); - _complete_top_at_mark_starts = _complete_top_at_mark_starts_base - - ((uintx) pgc_rs.base() >> ShenandoahHeapRegion::region_size_bytes_shift()); - if (ShenandoahPacing) { _pacer = new ShenandoahPacer(this); _pacer->setup_for_idle(); @@ -192,24 +185,6 @@ _pacer = NULL; } - { - ShenandoahHeapLocker locker(lock()); - for (size_t i = 0; i < _num_regions; i++) { - ShenandoahHeapRegion* r = new ShenandoahHeapRegion(this, - (HeapWord*) pgc_rs.base() + reg_size_words * i, - reg_size_words, - i, - i < num_committed_regions); - - _complete_top_at_mark_starts_base[i] = r->bottom(); - _next_top_at_mark_starts_base[i] = r->bottom(); - _regions[i] = r; - assert(!collection_set()->is_in(i), "New region should not be in collection set"); - } - - _free_set->rebuild(); - } - assert((((size_t) base()) & ShenandoahHeapRegion::region_size_bytes_mask()) == 0, "misaligned heap: "PTR_FORMAT, p2i(base())); @@ -277,6 +252,27 @@ _verifier = new ShenandoahVerifier(this, &_verification_bit_map); } + _complete_marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap0_region, _num_regions); + _next_marking_context = new ShenandoahMarkingContext(_heap_region, _bitmap1_region, _num_regions); + + { + ShenandoahHeapLocker locker(lock()); + for (size_t i = 0; i < _num_regions; i++) { + ShenandoahHeapRegion* r = new ShenandoahHeapRegion(this, + (HeapWord*) pgc_rs.base() + reg_size_words * i, + reg_size_words, + i, + i < num_committed_regions); + + _complete_marking_context->set_top_at_mark_start(i, r->bottom()); + _next_marking_context->set_top_at_mark_start(i, r->bottom()); + _regions[i] = r; + assert(!collection_set()->is_in(i), "New region should not be in collection set"); + } + + _free_set->rebuild(); + } + if (ShenandoahAlwaysPreTouch) { assert (!AlwaysPreTouch, "Should have been overridden"); @@ -291,11 +287,6 @@ _workers->run_task(&cl); } - _mark_bit_map0.initialize(_heap_region, _bitmap0_region); - _complete_mark_bit_map = &_mark_bit_map0; - - _mark_bit_map1.initialize(_heap_region, _bitmap1_region); - _next_mark_bit_map = &_mark_bit_map1; // Reserve aux bitmap for use in object_iterate(). We don't commit it here. ReservedSpace aux_bitmap(_bitmap_size, bitmap_page_size); @@ -407,12 +398,8 @@ _bytes_allocated_since_gc_start(0), _max_workers(MAX2(ConcGCThreads, ParallelGCThreads)), _ref_processor(NULL), - _next_top_at_mark_starts(NULL), - _next_top_at_mark_starts_base(NULL), - _complete_top_at_mark_starts(NULL), - _complete_top_at_mark_starts_base(NULL), - _mark_bit_map0(), - _mark_bit_map1(), + _complete_marking_context(NULL), + _next_marking_context(NULL), _aux_bit_map(), _connection_matrix(NULL), _verifier(NULL), @@ -476,11 +463,11 @@ while (region != NULL) { if (heap->is_bitmap_slice_committed(region)) { HeapWord* bottom = region->bottom(); - HeapWord* top = heap->next_top_at_mark_start(region->bottom()); + HeapWord* top = heap->next_marking_context()->top_at_mark_start(region->region_number()); if (top > bottom) { - heap->next_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + heap->next_marking_context()->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); } - assert(heap->is_next_bitmap_clear_range(bottom, region->end()), "must be clear"); + assert(heap->next_marking_context()->is_bitmap_clear_range(bottom, region->end()), "must be clear"); } region = _regions.next(); } @@ -511,17 +498,17 @@ assert(!region->is_empty_uncommitted(), "sanity"); assert(heap->is_bitmap_slice_committed(region), "sanity"); HeapWord* bottom = region->bottom(); - HeapWord* top = heap->next_top_at_mark_start(bottom); + HeapWord* top = heap->next_marking_context()->top_at_mark_start(region->region_number()); assert(top <= region->top(), "TAMS must smaller/equals than top: TAMS: "PTR_FORMAT", top: "PTR_FORMAT, p2i(top), p2i(region->top())); if (top > bottom) { - heap->complete_mark_bit_map()->copy_from(heap->next_mark_bit_map(), MemRegion(bottom, top)); - heap->set_complete_top_at_mark_start(bottom, top); - heap->next_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); - heap->set_next_top_at_mark_start(bottom, bottom); + heap->complete_marking_context()->mark_bit_map()->copy_from(heap->next_marking_context()->mark_bit_map(), MemRegion(bottom, top)); + heap->complete_marking_context()->set_top_at_mark_start(region->region_number(), top); + heap->next_marking_context()->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + heap->next_marking_context()->set_top_at_mark_start(region->region_number(), bottom); } - assert(heap->is_next_bitmap_clear_range(region->bottom(), region->end()), + assert(heap->next_marking_context()->is_bitmap_clear_range(region->bottom(), region->end()), "need clear next bitmap"); } region = _regions.claim_next(); @@ -538,24 +525,6 @@ _workers->run_task(&task); } -bool ShenandoahHeap::is_next_bitmap_clear() { - for (size_t idx = 0; idx < _num_regions; idx++) { - ShenandoahHeapRegion* r = get_region(idx); - if (is_bitmap_slice_committed(r) && !is_next_bitmap_clear_range(r->bottom(), r->end())) { - return false; - } - } - return true; -} - -bool ShenandoahHeap::is_next_bitmap_clear_range(HeapWord* start, HeapWord* end) { - return _next_mark_bit_map->getNextMarkedWordAddress(start, end) == end; -} - -bool ShenandoahHeap::is_complete_bitmap_clear_range(HeapWord* start, HeapWord* end) { - return _complete_mark_bit_map->getNextMarkedWordAddress(start, end) == end; -} - void ShenandoahHeap::print_on(outputStream* st) const { st->print_cr("Shenandoah Heap"); st->print_cr(" " SIZE_FORMAT "K total, " SIZE_FORMAT "K committed, " SIZE_FORMAT "K used", @@ -1647,7 +1616,7 @@ bool heap_region_do(ShenandoahHeapRegion* r) { r->clear_live_data(); - sh->set_next_top_at_mark_start(r->bottom(), r->top()); + sh->next_marking_context()->set_top_at_mark_start(r->region_number(), r->top()); return false; } }; @@ -1655,7 +1624,7 @@ void ShenandoahHeap::op_init_mark() { assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should be at safepoint"); - assert(is_next_bitmap_clear(), "need clear marking bitmap"); + assert(next_marking_context()->is_bitmap_clear(), "need clear marking bitmap"); if (ShenandoahVerify) { verifier()->verify_before_concmark(); @@ -1721,7 +1690,7 @@ ShenandoahHeapRegion* r = get_region(i); if (!r->is_active()) continue; - HeapWord* tams = complete_top_at_mark_start(r->bottom()); + HeapWord* tams = complete_marking_context()->top_at_mark_start(r->region_number()); HeapWord* top = r->top(); if (top > tams) { r->increase_live_data_alloc_words(pointer_delta(top, tams)); @@ -2023,19 +1992,9 @@ } void ShenandoahHeap::swap_mark_bitmaps() { - // Swap bitmaps. - MarkBitMap* tmp1 = _complete_mark_bit_map; - _complete_mark_bit_map = _next_mark_bit_map; - _next_mark_bit_map = tmp1; - - // Swap top-at-mark-start pointers - HeapWord** tmp2 = _complete_top_at_mark_starts; - _complete_top_at_mark_starts = _next_top_at_mark_starts; - _next_top_at_mark_starts = tmp2; - - HeapWord** tmp3 = _complete_top_at_mark_starts_base; - _complete_top_at_mark_starts_base = _next_top_at_mark_starts_base; - _next_top_at_mark_starts_base = tmp3; + ShenandoahMarkingContext* tmp = _complete_marking_context; + _complete_marking_context = _next_marking_context; + _next_marking_context = tmp; } @@ -2123,8 +2082,8 @@ return false; } obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); - shenandoah_assert_not_forwarded_if(NULL, obj, _heap->is_concurrent_mark_in_progress() || _heap->is_concurrent_traversal_in_progress()) - return _heap->is_marked_next(obj); + shenandoah_assert_not_forwarded_if(NULL, obj, _heap->is_concurrent_mark_in_progress() || _heap->is_concurrent_traversal_in_progress()); + return _heap->next_marking_context()->is_marked(obj); } bool ShenandoahIsAliveClosure::do_object_b(oop obj) { @@ -2132,7 +2091,7 @@ return false; } shenandoah_assert_not_forwarded(NULL, obj); - return _heap->is_marked_next(obj); + return _heap->next_marking_context()->is_marked(obj); } BoolObjectClosure* ShenandoahHeap::is_alive_closure() { @@ -2339,14 +2298,6 @@ return _monitoring_support; } -MarkBitMap* ShenandoahHeap::complete_mark_bit_map() { - return _complete_mark_bit_map; -} - -MarkBitMap* ShenandoahHeap::next_mark_bit_map() { - return _next_mark_bit_map; -} - address ShenandoahHeap::in_cset_fast_test_addr() { ShenandoahHeap* heap = ShenandoahHeap::heap(); assert(heap->collection_set() != NULL, "Sanity"); @@ -2374,26 +2325,6 @@ return _pacer; } -void ShenandoahHeap::set_next_top_at_mark_start(HeapWord* region_base, HeapWord* addr) { - uintx index = ((uintx) region_base) >> ShenandoahHeapRegion::region_size_bytes_shift(); - _next_top_at_mark_starts[index] = addr; -} - -HeapWord* ShenandoahHeap::next_top_at_mark_start(HeapWord* region_base) { - uintx index = ((uintx) region_base) >> ShenandoahHeapRegion::region_size_bytes_shift(); - return _next_top_at_mark_starts[index]; -} - -void ShenandoahHeap::set_complete_top_at_mark_start(HeapWord* region_base, HeapWord* addr) { - uintx index = ((uintx) region_base) >> ShenandoahHeapRegion::region_size_bytes_shift(); - _complete_top_at_mark_starts[index] = addr; -} - -HeapWord* ShenandoahHeap::complete_top_at_mark_start(HeapWord* region_base) { - uintx index = ((uintx) region_base) >> ShenandoahHeapRegion::region_size_bytes_shift(); - return _complete_top_at_mark_starts[index]; -} - void ShenandoahHeap::set_degenerated_gc_in_progress(bool in_progress) { _degenerated_gc_in_progress.set_cond(in_progress); } @@ -2497,9 +2428,9 @@ while (r != NULL) { if (_heap->in_collection_set(r)) { HeapWord* bottom = r->bottom(); - HeapWord* top = _heap->complete_top_at_mark_start(r->bottom()); + HeapWord* top = _heap->complete_marking_context()->top_at_mark_start(r->region_number()); if (top > bottom) { - _heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + _heap->complete_marking_context()->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); } } else { if (r->is_active()) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -43,6 +43,7 @@ class ShenandoahControlThread; class ShenandoahFastRegionSet; class ShenandoahHeuristics; +class ShenandoahMarkingContext; class ShenandoahPhaseTimings; class ShenandoahHeap; class ShenandoahHeapRegion; @@ -282,17 +283,10 @@ volatile size_t _committed; MarkBitMap _verification_bit_map; - MarkBitMap _mark_bit_map0; - MarkBitMap _mark_bit_map1; - MarkBitMap* _complete_mark_bit_map; - MarkBitMap* _next_mark_bit_map; MarkBitMap _aux_bit_map; - HeapWord** _complete_top_at_mark_starts; - HeapWord** _complete_top_at_mark_starts_base; - - HeapWord** _next_top_at_mark_starts; - HeapWord** _next_top_at_mark_starts_base; + ShenandoahMarkingContext* _complete_marking_context; + ShenandoahMarkingContext* _next_marking_context; volatile size_t _bytes_allocated_since_gc_start; @@ -501,14 +495,6 @@ template inline bool in_collection_set(T obj) const; - inline bool allocated_after_next_mark_start(HeapWord* addr) const; - void set_next_top_at_mark_start(HeapWord* region_base, HeapWord* addr); - HeapWord* next_top_at_mark_start(HeapWord* region_base); - - inline bool allocated_after_complete_mark_start(HeapWord* addr) const; - void set_complete_top_at_mark_start(HeapWord* region_base, HeapWord* addr); - HeapWord* complete_top_at_mark_start(HeapWord* region_base); - // Evacuates object src. Returns the evacuated object if this thread // succeeded, otherwise rolls back the evacuation and returns the // evacuated object by the competing thread. @@ -541,14 +527,13 @@ void reset_next_mark_bitmap(); void reset_next_mark_bitmap_traversal(); - MarkBitMap* complete_mark_bit_map(); - MarkBitMap* next_mark_bit_map(); - inline bool is_marked_complete(oop obj) const; - inline bool mark_next(oop obj) const; - inline bool is_marked_next(oop obj) const; - bool is_next_bitmap_clear(); - bool is_next_bitmap_clear_range(HeapWord* start, HeapWord* end); - bool is_complete_bitmap_clear_range(HeapWord* start, HeapWord* end); + inline ShenandoahMarkingContext* complete_marking_context() const { + return _complete_marking_context; + } + + inline ShenandoahMarkingContext* next_marking_context() const { + return _next_marking_context; + } bool commit_bitmap_slice(ShenandoahHeapRegion *r); bool uncommit_bitmap_slice(ShenandoahHeapRegion *r); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp @@ -38,6 +38,7 @@ #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "gc/shenandoah/shenandoahControlThread.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahThreadLocalData.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" #include "oops/oop.inline.hpp" @@ -67,27 +68,6 @@ return _heap->get_region(new_index - 1); } -/* - * Marks the object. Returns true if the object has not been marked before and has - * been marked by this thread. Returns false if the object has already been marked, - * or if a competing thread succeeded in marking this object. - */ -inline bool ShenandoahHeap::mark_next(oop obj) const { - shenandoah_assert_not_forwarded(NULL, obj); - HeapWord* addr = (HeapWord*) obj; - return (! allocated_after_next_mark_start(addr)) && _next_mark_bit_map->parMark(addr); -} - -inline bool ShenandoahHeap::is_marked_next(oop obj) const { - HeapWord* addr = (HeapWord*) obj; - return allocated_after_next_mark_start(addr) || _next_mark_bit_map->isMarked(addr); -} - -inline bool ShenandoahHeap::is_marked_complete(oop obj) const { - HeapWord* addr = (HeapWord*) obj; - return allocated_after_complete_mark_start(addr) || _complete_mark_bit_map->isMarked(addr); -} - inline bool ShenandoahHeap::has_forwarded_objects() const { return _gc_state.is_set(HAS_FORWARDED); } @@ -364,7 +344,7 @@ } inline bool ShenandoahHeap::requires_marking(const void* entry) const { - return ! is_marked_next(oop(entry)); + return ! _next_marking_context->is_marked(oop(entry)); } bool ShenandoahHeap::region_in_collection_set(size_t region_index) const { @@ -425,20 +405,6 @@ return _gc_state.is_set(UPDATEREFS); } -inline bool ShenandoahHeap::allocated_after_next_mark_start(HeapWord* addr) const { - uintx index = ((uintx) addr) >> ShenandoahHeapRegion::region_size_bytes_shift(); - HeapWord* top_at_mark_start = _next_top_at_mark_starts[index]; - bool alloc_after_mark_start = addr >= top_at_mark_start; - return alloc_after_mark_start; -} - -inline bool ShenandoahHeap::allocated_after_complete_mark_start(HeapWord* addr) const { - uintx index = ((uintx) addr) >> ShenandoahHeapRegion::region_size_bytes_shift(); - HeapWord* top_at_mark_start = _complete_top_at_mark_starts[index]; - bool alloc_after_mark_start = addr >= top_at_mark_start; - return alloc_after_mark_start; -} - template inline void ShenandoahHeap::marked_object_iterate(ShenandoahHeapRegion* region, T* cl) { marked_object_iterate(region, cl, region->top()); @@ -454,8 +420,8 @@ assert(BrooksPointer::word_offset() < 0, "skip_delta calculation below assumes the forwarding ptr is before obj"); assert(! region->is_humongous_continuation(), "no humongous continuation regions here"); - MarkBitMap* mark_bit_map = _complete_mark_bit_map; - HeapWord* tams = complete_top_at_mark_start(region->bottom()); + MarkBitMap* mark_bit_map = _complete_marking_context->mark_bit_map(); + HeapWord* tams = _complete_marking_context->top_at_mark_start(region->region_number()); size_t skip_bitmap_delta = BrooksPointer::word_size() + 1; size_t skip_objsize_delta = BrooksPointer::word_size() /* + actual obj.size() below */; @@ -535,7 +501,7 @@ template inline void ShenandoahHeap::do_object_marked_complete(T* cl, oop obj) { assert(oopDesc::is_oop(obj), "sanity"); - assert(is_marked_complete(obj), "object expected to be marked"); + assert(_complete_marking_context->is_marked(obj), "object expected to be marked"); cl->do_object(obj); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp @@ -29,6 +29,7 @@ #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahTraversalGC.hpp" #include "gc/shared/space.inline.hpp" #include "memory/iterator.inline.hpp" @@ -431,8 +432,8 @@ st->print("|BTE " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12), p2i(bottom()), p2i(top()), p2i(end())); st->print("|TAMS " INTPTR_FORMAT_W(12) ", " INTPTR_FORMAT_W(12), - p2i(_heap->complete_top_at_mark_start(_bottom)), - p2i(_heap->next_top_at_mark_start(_bottom))); + p2i(_heap->complete_marking_context()->top_at_mark_start(region_number())), + p2i(_heap->next_marking_context()->top_at_mark_start(region_number()))); st->print("|U %3d%%", (int) ((double) used() * 100 / capacity())); st->print("|T %3d%%", (int) ((double) get_tlab_allocs() * 100 / capacity())); st->print("|G %3d%%", (int) ((double) get_gclab_allocs() * 100 / capacity())); @@ -515,19 +516,19 @@ // in that regions is going to be new objects. if (ShenandoahRecycleClearsBitmap && !_heap->is_full_gc_in_progress()) { HeapWord* r_bottom = bottom(); - HeapWord* top = _heap->complete_top_at_mark_start(r_bottom); + HeapWord* top = _heap->complete_marking_context()->top_at_mark_start(region_number()); if (top > r_bottom) { - _heap->complete_mark_bit_map()->clear_range_large(MemRegion(r_bottom, top)); + _heap->complete_marking_context()->mark_bit_map()->clear_range_large(MemRegion(r_bottom, top)); } - assert(_heap->is_next_bitmap_clear_range(bottom(), end()), "must be clear"); - _heap->set_next_top_at_mark_start(bottom(), bottom()); + assert(_heap->next_marking_context()->is_bitmap_clear_range(bottom(), end()), "must be clear"); + _heap->next_marking_context()->set_top_at_mark_start(region_number(), bottom()); } // We can only safely reset the C-TAMS pointer if the bitmap is clear for that region. - assert(_heap->is_complete_bitmap_clear_range(bottom(), end()), "must be clear"); + assert(_heap->complete_marking_context()->is_bitmap_clear_range(bottom(), end()), "must be clear"); - _heap->set_complete_top_at_mark_start(bottom(), bottom()); + _heap->complete_marking_context()->set_top_at_mark_start(region_number(), bottom()); if (UseShenandoahMatrix) { _heap->connection_matrix()->clear_region(region_number()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp @@ -28,6 +28,7 @@ #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.hpp" #include "gc/shenandoah/shenandoahHeuristics.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" int ShenandoahHeuristics::compare_by_garbage(RegionData a, RegionData b) { if (a._garbage > b._garbage) @@ -180,7 +181,7 @@ // Reclaim humongous regions here, and count them as the immediate garbage #ifdef ASSERT bool reg_live = region->has_live(); - bool bm_live = heap->is_marked_complete(oop(region->bottom() + BrooksPointer::word_size())); + bool bm_live = heap->complete_marking_context()->is_marked(oop(region->bottom() + BrooksPointer::word_size())); assert(reg_live == bm_live, "Humongous liveness and marks should agree. Region live: %s; Bitmap live: %s; Region Live Words: " SIZE_FORMAT, BOOL_TO_STR(reg_live), BOOL_TO_STR(bm_live), region->get_live_data_words()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp @@ -36,6 +36,7 @@ #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahRootProcessor.hpp" #include "gc/shenandoah/shenandoahTraversalGC.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" @@ -106,7 +107,7 @@ // c. Reset the bitmaps for new marking heap->reset_next_mark_bitmap(); - assert(heap->is_next_bitmap_clear(), "sanity"); + assert(heap->next_marking_context()->is_bitmap_clear(), "sanity"); // d. Abandon reference discovery and clear all discovered references. ReferenceProcessor* rp = heap->ref_processor(); @@ -192,7 +193,7 @@ ShenandoahPrepareForMarkClosure() : _heap(ShenandoahHeap::heap()) {} bool heap_region_do(ShenandoahHeapRegion *r) { - _heap->set_next_top_at_mark_start(r->bottom(), r->top()); + _heap->next_marking_context()->set_top_at_mark_start(r->region_number(), r->top()); r->clear_live_data(); r->set_concurrent_iteration_safe_limit(r->top()); return false; @@ -274,8 +275,8 @@ void do_object(oop p) { assert(_from_region != NULL, "must set before work"); - assert(_heap->is_marked_complete(p), "must be marked"); - assert(!_heap->allocated_after_complete_mark_start((HeapWord*) p), "must be truly marked"); + assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); + assert(!_heap->complete_marking_context()->allocated_after_mark_start((HeapWord*) p), "must be truly marked"); size_t obj_size = p->size() + BrooksPointer::word_size(); if (_compact_point + obj_size > _to_region->end()) { @@ -450,7 +451,7 @@ bool heap_region_do(ShenandoahHeapRegion* r) { if (r->is_humongous_start()) { oop humongous_obj = oop(r->bottom() + BrooksPointer::word_size()); - if (!_heap->is_marked_complete(humongous_obj)) { + if (!_heap->complete_marking_context()->is_marked(humongous_obj)) { assert(!r->has_live(), "Region " SIZE_FORMAT " is not marked, should not have live", r->region_number()); _heap->trash_humongous_region_at(r); @@ -464,7 +465,7 @@ "Region " SIZE_FORMAT " should have live", r->region_number()); } else if (r->is_regular()) { if (!r->has_live()) { - assert(_heap->is_complete_bitmap_clear_range(r->bottom(), r->end()), + assert(_heap->complete_marking_context()->is_bitmap_clear_range(r->bottom(), r->end()), "Region " SIZE_FORMAT " should not have marks in bitmap", r->region_number()); r->make_trash(); } @@ -517,7 +518,7 @@ T o = RawAccess<>::oop_load(p); if (!CompressedOops::is_null(o)) { oop obj = CompressedOops::decode_not_null(o); - assert(_heap->is_marked_complete(obj), "must be marked"); + assert(_heap->complete_marking_context()->is_marked(obj), "must be marked"); oop forw = oop(BrooksPointer::get_raw(obj)); RawAccess::oop_store(p, forw); if (MATRIX && UseShenandoahMatrix) { @@ -558,7 +559,7 @@ _heap(ShenandoahHeap::heap()) { } void do_object(oop p) { - assert(_heap->is_marked_complete(p), "must be marked"); + assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); HeapWord* forw = BrooksPointer::get_raw(p); if (MATRIX) { _cl.set_new_obj_offset(pointer_delta((HeapWord *) p, forw)); @@ -661,7 +662,7 @@ _heap(ShenandoahHeap::heap()), _worker_id(worker_id) {} void do_object(oop p) { - assert(_heap->is_marked_complete(p), "must be marked"); + assert(_heap->complete_marking_context()->is_marked(p), "must be marked"); size_t size = (size_t)p->size(); HeapWord* compact_to = BrooksPointer::get_raw(p); HeapWord* compact_from = (HeapWord*) p; @@ -720,7 +721,7 @@ // NOTE: See blurb at ShenandoahMCResetCompleteBitmapTask on why we need to skip // pinned regions. if (!r->is_pinned()) { - _heap->set_complete_top_at_mark_start(r->bottom(), r->bottom()); + _heap->complete_marking_context()->set_top_at_mark_start(r->region_number(), r->bottom()); } size_t live = r->used(); @@ -841,11 +842,11 @@ while (region != NULL) { if (heap->is_bitmap_slice_committed(region) && !region->is_pinned()) { HeapWord* bottom = region->bottom(); - HeapWord* top = heap->complete_top_at_mark_start(region->bottom()); + HeapWord* top = heap->complete_marking_context()->top_at_mark_start(region->region_number()); if (top > bottom && region->has_live()) { - heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + heap->complete_marking_context()->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); } - assert(heap->is_complete_bitmap_clear_range(bottom, region->end()), "must be clear"); + assert(heap->complete_marking_context()->is_bitmap_clear_range(bottom, region->end()), "must be clear"); } region = _regions.next(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp new file mode 100644 --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates. + * + * 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/shared/markBitMap.inline.hpp" +#include "gc/shenandoah/shenandoahHeap.hpp" +#include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.hpp" + +ShenandoahMarkingContext::ShenandoahMarkingContext(MemRegion heap_region, MemRegion bitmap_region, size_t num_regions) : + _top_at_mark_starts_base(NEW_C_HEAP_ARRAY(HeapWord*, num_regions, mtGC)), + _top_at_mark_starts(_top_at_mark_starts_base - + ((uintx) heap_region.start() >> ShenandoahHeapRegion::region_size_bytes_shift())) { + _mark_bit_map.initialize(heap_region, bitmap_region); +} + +bool ShenandoahMarkingContext::is_bitmap_clear() const { + ShenandoahHeap* heap = ShenandoahHeap::heap(); + size_t num_regions = heap->num_regions(); + for (size_t idx = 0; idx < num_regions; idx++) { + ShenandoahHeapRegion* r = heap->get_region(idx); + if (heap->is_bitmap_slice_committed(r) && !is_bitmap_clear_range(r->bottom(), r->end())) { + return false; + } + } + return true; +} + +bool ShenandoahMarkingContext::is_bitmap_clear_range(HeapWord* start, HeapWord* end) const { + return _mark_bit_map.getNextMarkedWordAddress(start, end) == end; +} + +void ShenandoahMarkingContext::set_top_at_mark_start(size_t region_number, HeapWord* addr) { + _top_at_mark_starts_base[region_number] = addr; +} + +HeapWord* ShenandoahMarkingContext::top_at_mark_start(size_t region_number) const { + return _top_at_mark_starts_base[region_number]; +} + diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp new file mode 100644 --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates. + * + * 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. + * + */ + +#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_HPP +#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_HPP + +#include "gc/shared/markBitMap.hpp" +#include "memory/allocation.hpp" +#include "memory/memRegion.hpp" +#include "oops/oopsHierarchy.hpp" + +class HeapWord; + +/** + * Encapsulate a marking bitmap with a top-at-mark-start array. + */ +class ShenandoahMarkingContext : public CHeapObj { +private: + MarkBitMap _mark_bit_map; + + HeapWord** const _top_at_mark_starts_base; + HeapWord** const _top_at_mark_starts; + +public: + ShenandoahMarkingContext(MemRegion heap_region, MemRegion bitmap_region, size_t num_regions); + + /* + * Marks the object. Returns true if the object has not been marked before and has + * been marked by this thread. Returns false if the object has already been marked, + * or if a competing thread succeeded in marking this object. + */ + inline bool mark(oop obj); + + inline bool is_marked(oop obj) const; + + inline bool allocated_after_mark_start(HeapWord* addr) const; + + inline MarkBitMap* mark_bit_map(); + HeapWord* top_at_mark_start(size_t region_number) const; + void set_top_at_mark_start(size_t region_number, HeapWord* tams); + + bool is_bitmap_clear() const; + bool is_bitmap_clear_range(HeapWord* start, HeapWord* end) const; + +}; + +#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp new file mode 100644 --- /dev/null +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates. + * + * 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. + * + */ + +#ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_INLINE_HPP +#define SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_INLINE_HPP + +#include "gc/shenandoah/shenandoahMarkingContext.hpp" + +inline MarkBitMap* ShenandoahMarkingContext::mark_bit_map() { + return &_mark_bit_map; +} + +inline bool ShenandoahMarkingContext::mark(oop obj) { + shenandoah_assert_not_forwarded(NULL, obj); + HeapWord* addr = (HeapWord*) obj; + return (! allocated_after_mark_start(addr)) && _mark_bit_map.parMark(addr); +} + +inline bool ShenandoahMarkingContext::is_marked(oop obj) const { + HeapWord* addr = (HeapWord*) obj; + return allocated_after_mark_start(addr) || _mark_bit_map.isMarked(addr); +} + +inline bool ShenandoahMarkingContext::allocated_after_mark_start(HeapWord* addr) const { + uintx index = ((uintx) addr) >> ShenandoahHeapRegion::region_size_bytes_shift(); + HeapWord* top_at_mark_start = _top_at_mark_starts[index]; + bool alloc_after_mark_start = addr >= top_at_mark_start; + return alloc_after_mark_start; +} + +#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHMARKINGCONTEXT_INLINE_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPrinter.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPrinter.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahPrinter.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPrinter.cpp @@ -28,6 +28,7 @@ #include "memory/iterator.inline.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahPrinter.hpp" class ShenandoahPrintAllRefsOopClosure: public BasicOopIterateClosure { @@ -47,7 +48,7 @@ tty->print_cr("%s " INT32_FORMAT " (" PTR_FORMAT ")-> " PTR_FORMAT " (marked: %s) (%s " PTR_FORMAT ")", _prefix, _index, p2i(p), p2i(o), - BOOL_TO_STR(ShenandoahHeap::heap()->is_marked_complete(o)), + BOOL_TO_STR(ShenandoahHeap::heap()->complete_marking_context()->is_marked(o)), o->klass()->internal_name(), p2i(o->klass())); } else { tty->print_cr("%s " INT32_FORMAT " (" PTR_FORMAT " dirty -> " PTR_FORMAT " (not in heap, possibly corrupted or dirty)", @@ -80,7 +81,7 @@ if (ShenandoahHeap::heap()->is_in(p)) { tty->print_cr("%s object " PTR_FORMAT " (marked: %s) (%s " PTR_FORMAT ") refers to:", _prefix, p2i(p), - BOOL_TO_STR(ShenandoahHeap::heap()->is_marked_complete(p)), + BOOL_TO_STR(ShenandoahHeap::heap()->complete_marking_context()->is_marked(p)), p->klass()->internal_name(), p2i(p->klass())); ShenandoahPrintAllRefsOopClosure cl(_prefix); p->oop_iterate(&cl); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp b/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp @@ -31,6 +31,7 @@ #include "gc/shenandoah/shenandoahCollectionSet.inline.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahStringDedup.hpp" #include "gc/shenandoah/shenandoahStrDedupQueue.hpp" #include "gc/shenandoah/shenandoahUtils.hpp" @@ -111,7 +112,7 @@ ShenandoahIsMarkedNextClosure() : _heap(ShenandoahHeap::heap()) { } bool do_object_b(oop obj) { - return _heap->is_marked_next(obj); + return _heap->next_marking_context()->is_marked(obj); } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp @@ -41,6 +41,7 @@ #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp" #include "gc/shenandoah/shenandoahHeuristics.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahOopClosures.inline.hpp" #include "gc/shenandoah/shenandoahTraversalGC.hpp" #include "gc/shenandoah/shenandoahRootProcessor.hpp" @@ -112,7 +113,7 @@ oop* p = (oop*) &buffer[i]; oop obj = RawAccess<>::oop_load(p); shenandoah_assert_not_forwarded(p, obj); - if (_heap->mark_next(obj)) { + if (_heap->next_marking_context()->mark(obj)) { _queue->push(ShenandoahMarkTask(obj)); } } @@ -341,12 +342,12 @@ ShenandoahHeapRegion* region = heap->get_region(i); if (heap->is_bitmap_slice_committed(region)) { if (_traversal_set.is_in(i)) { - heap->set_next_top_at_mark_start(region->bottom(), region->top()); + heap->next_marking_context()->set_top_at_mark_start(region->region_number(), region->top()); region->clear_live_data(); - assert(heap->is_next_bitmap_clear_range(region->bottom(), region->end()), "bitmap for traversal regions must be cleared"); + assert(heap->next_marking_context()->is_bitmap_clear_range(region->bottom(), region->end()), "bitmap for traversal regions must be cleared"); } else { // Everything outside the traversal set is always considered live. - heap->set_next_top_at_mark_start(region->bottom(), region->bottom()); + heap->next_marking_context()->set_top_at_mark_start(region->region_number(), region->bottom()); } if (_root_regions.is_in(i)) { assert(!region->in_collection_set(), "roots must not overlap with cset"); @@ -367,7 +368,7 @@ _heap->make_parsable(true); - assert(_heap->is_next_bitmap_clear(), "need clean mark bitmap"); + assert(_heap->next_marking_context()->is_bitmap_clear(), "need clean mark bitmap"); ShenandoahFreeSet* free_set = _heap->free_set(); ShenandoahCollectionSet* collection_set = _heap->collection_set(); @@ -713,13 +714,13 @@ free_regions->clear(); for (size_t i = 0; i < num_regions; i++) { ShenandoahHeapRegion* r = _heap->get_region(i); - bool not_allocated = _heap->next_top_at_mark_start(r->bottom()) == r->top(); + bool not_allocated = _heap->next_marking_context()->top_at_mark_start(r->region_number()) == r->top(); bool candidate = traversal_regions->is_in(r) && !r->has_live() && not_allocated; if (r->is_humongous_start() && candidate) { // Trash humongous. HeapWord* humongous_obj = r->bottom() + BrooksPointer::word_size(); - assert(!_heap->is_marked_next(oop(humongous_obj)), "must not be marked"); + assert(!_heap->next_marking_context()->is_marked(oop(humongous_obj)), "must not be marked"); r->make_trash(); while (i + 1 < num_regions && _heap->get_region(i + 1)->is_humongous_continuation()) { i++; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.inline.hpp @@ -29,6 +29,7 @@ #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahStringDedup.hpp" #include "gc/shenandoah/shenandoahTraversalGC.hpp" #include "gc/shenandoah/shenandoahTaskqueue.hpp" @@ -76,7 +77,7 @@ } } - if (_heap->mark_next(obj)) { + if (_heap->next_marking_context()->mark(obj)) { bool succeeded = queue->push(ShenandoahMarkTask(obj)); assert(succeeded, "must succeed to push to task queue"); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp @@ -29,6 +29,7 @@ #include "gc/shenandoah/shenandoahPhaseTimings.hpp" #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" +#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahRootProcessor.hpp" #include "gc/shenandoah/shenandoahTaskqueue.hpp" #include "gc/shenandoah/shenandoahVerifier.hpp" @@ -193,11 +194,11 @@ // skip break; case ShenandoahVerifier::_verify_marked_next: - check(ShenandoahAsserts::_safe_all, obj, _heap->is_marked_next(obj), + check(ShenandoahAsserts::_safe_all, obj, _heap->next_marking_context()->is_marked(obj), "Must be marked in next bitmap"); break; case ShenandoahVerifier::_verify_marked_complete: - check(ShenandoahAsserts::_safe_all, obj, _heap->is_marked_complete(obj), + check(ShenandoahAsserts::_safe_all, obj, _heap->complete_marking_context()->is_marked(obj), "Must be marked in complete bitmap"); break; default: @@ -374,10 +375,10 @@ verify(r, r->capacity() == ShenandoahHeapRegion::region_size_bytes(), "Capacity should match region size"); - verify(r, r->bottom() <= _heap->complete_top_at_mark_start(r->bottom()), + verify(r, r->bottom() <= _heap->complete_marking_context()->top_at_mark_start(r->region_number()), "Region top should not be less than bottom"); - verify(r, _heap->complete_top_at_mark_start(r->bottom()) <= r->top(), + verify(r, _heap->complete_marking_context()->top_at_mark_start(r->region_number()) <= r->top(), "Complete TAMS should not be larger than top"); verify(r, r->get_live_data_bytes() <= r->capacity(), @@ -536,7 +537,7 @@ virtual void work_humongous(ShenandoahHeapRegion *r, ShenandoahVerifierStack& stack, ShenandoahVerifyOopClosure& cl) { size_t processed = 0; HeapWord* obj = r->bottom() + BrooksPointer::word_size(); - if (_heap->is_marked_complete((oop)obj)) { + if (_heap->complete_marking_context()->is_marked((oop)obj)) { verify_and_follow(obj, stack, cl, &processed); } Atomic::add(processed, &_processed); @@ -544,8 +545,8 @@ virtual void work_regular(ShenandoahHeapRegion *r, ShenandoahVerifierStack &stack, ShenandoahVerifyOopClosure &cl) { size_t processed = 0; - MarkBitMap* mark_bit_map = _heap->complete_mark_bit_map(); - HeapWord* tams = _heap->complete_top_at_mark_start(r->bottom()); + MarkBitMap* mark_bit_map = _heap->complete_marking_context()->mark_bit_map(); + HeapWord* tams = _heap->complete_marking_context()->top_at_mark_start(r->region_number()); // Bitmaps, before TAMS if (tams > r->bottom()) { # HG changeset patch # User rkennke # Date 1531934070 -7200 # Wed Jul 18 19:14:30 2018 +0200 # Node ID 3f83f4bfce4d583715b91b80de14ccad9daaa936 # Parent b68562c62ddf0512a6764f468307c5b3a2e67d75 [mq]: refactor-marking-context.01 diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp @@ -62,11 +62,14 @@ stringStream ss; r->print_on(&ss); + ShenandoahMarkingContext* const next_ctx = heap->next_marking_context(); + ShenandoahMarkingContext* const compl_ctx = heap->next_marking_context(); + msg.append(" " PTR_FORMAT " - klass " PTR_FORMAT " %s\n", p2i(obj), p2i(obj->klass()), obj->klass()->external_name()); - msg.append(" %3s allocated after complete mark start\n", heap->complete_marking_context()->allocated_after_mark_start((HeapWord *) obj) ? "" : "not"); - msg.append(" %3s allocated after next mark start\n", heap->next_marking_context()->allocated_after_mark_start((HeapWord *) obj) ? "" : "not"); - msg.append(" %3s marked complete\n", heap->complete_marking_context()->is_marked(obj) ? "" : "not"); - msg.append(" %3s marked next\n", heap->next_marking_context()->is_marked(obj) ? "" : "not"); + msg.append(" %3s allocated after complete mark start\n", compl_ctx->allocated_after_mark_start((HeapWord *) obj) ? "" : "not"); + msg.append(" %3s allocated after next mark start\n", next_ctx->allocated_after_mark_start((HeapWord *) obj) ? "" : "not"); + msg.append(" %3s marked complete\n", compl_ctx->is_marked(obj) ? "" : "not"); + msg.append(" %3s marked next\n", next_ctx->is_marked(obj) ? "" : "not"); msg.append(" %3s in collection set\n", heap->in_collection_set(obj) ? "" : "not"); if (heap->traversal_gc() != NULL) { msg.append(" %3s in root set\n", heap->traversal_gc()->root_regions()->is_in((HeapWord*) obj) ? "" : "not"); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -460,14 +460,15 @@ void work(uint worker_id) { ShenandoahHeapRegion* region = _regions.next(); ShenandoahHeap* heap = ShenandoahHeap::heap(); + ShenandoahMarkingContext* const ctx = heap->next_marking_context(); while (region != NULL) { if (heap->is_bitmap_slice_committed(region)) { HeapWord* bottom = region->bottom(); - HeapWord* top = heap->next_marking_context()->top_at_mark_start(region->region_number()); + HeapWord* top = ctx->top_at_mark_start(region->region_number()); if (top > bottom) { - heap->next_marking_context()->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + ctx->clear_bitmap(bottom, top); } - assert(heap->next_marking_context()->is_bitmap_clear_range(bottom, region->end()), "must be clear"); + assert(ctx->is_bitmap_clear_range(bottom, region->end()), "must be clear"); } region = _regions.next(); } @@ -493,22 +494,24 @@ void work(uint worker_id) { ShenandoahHeap* heap = ShenandoahHeap::heap(); ShenandoahHeapRegion* region = _regions.claim_next(); + ShenandoahMarkingContext* const next_ctx = heap->next_marking_context(); + ShenandoahMarkingContext* const compl_ctx = heap->next_marking_context(); while (region != NULL) { if (!region->is_trash()) { assert(!region->is_empty_uncommitted(), "sanity"); assert(heap->is_bitmap_slice_committed(region), "sanity"); HeapWord* bottom = region->bottom(); - HeapWord* top = heap->next_marking_context()->top_at_mark_start(region->region_number()); + HeapWord* top = next_ctx->top_at_mark_start(region->region_number()); assert(top <= region->top(), "TAMS must smaller/equals than top: TAMS: "PTR_FORMAT", top: "PTR_FORMAT, p2i(top), p2i(region->top())); if (top > bottom) { - heap->complete_marking_context()->mark_bit_map()->copy_from(heap->next_marking_context()->mark_bit_map(), MemRegion(bottom, top)); - heap->complete_marking_context()->set_top_at_mark_start(region->region_number(), top); - heap->next_marking_context()->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); - heap->next_marking_context()->set_top_at_mark_start(region->region_number(), bottom); + compl_ctx->mark_bit_map()->copy_from(heap->next_marking_context()->mark_bit_map(), MemRegion(bottom, top)); + compl_ctx->set_top_at_mark_start(region->region_number(), top); + next_ctx->clear_bitmap(bottom, top); + next_ctx->set_top_at_mark_start(region->region_number(), bottom); } - assert(heap->next_marking_context()->is_bitmap_clear_range(region->bottom(), region->end()), + assert(next_ctx->is_bitmap_clear_range(region->bottom(), region->end()), "need clear next bitmap"); } region = _regions.claim_next(); @@ -1991,7 +1994,7 @@ op_full(GCCause::_shenandoah_upgrade_to_full_gc); } -void ShenandoahHeap::swap_mark_bitmaps() { +void ShenandoahHeap::swap_mark_contexts() { ShenandoahMarkingContext* tmp = _complete_marking_context; _complete_marking_context = _next_marking_context; _next_marking_context = tmp; @@ -2004,7 +2007,7 @@ // If we needed to update refs, and concurrent marking has been cancelled, // we need to finish updating references. set_has_forwarded_objects(false); - swap_mark_bitmaps(); + swap_mark_contexts(); } set_concurrent_mark_in_progress(false); @@ -2425,12 +2428,13 @@ ShenandoahWorkerSession worker_session(worker_id); SuspendibleThreadSetJoiner stsj(_concurrent && ShenandoahSuspendibleWorkers); ShenandoahHeapRegion* r = _regions->next(); + ShenandoahMarkingContext* const ctx = _heap->complete_marking_context(); while (r != NULL) { if (_heap->in_collection_set(r)) { HeapWord* bottom = r->bottom(); - HeapWord* top = _heap->complete_marking_context()->top_at_mark_start(r->region_number()); + HeapWord* top = ctx->top_at_mark_start(r->region_number()); if (top > bottom) { - _heap->complete_marking_context()->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + ctx->clear_bitmap(bottom, top); } } else { if (r->is_active()) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -609,7 +609,7 @@ GCTimer* gc_timer() const; - void swap_mark_bitmaps(); + void swap_mark_contexts(); void cancel_gc(GCCause::Cause cause); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp @@ -420,8 +420,9 @@ assert(BrooksPointer::word_offset() < 0, "skip_delta calculation below assumes the forwarding ptr is before obj"); assert(! region->is_humongous_continuation(), "no humongous continuation regions here"); - MarkBitMap* mark_bit_map = _complete_marking_context->mark_bit_map(); - HeapWord* tams = _complete_marking_context->top_at_mark_start(region->region_number()); + ShenandoahMarkingContext* const ctx = complete_marking_context(); + MarkBitMap* mark_bit_map = ctx->mark_bit_map(); + HeapWord* tams = ctx->top_at_mark_start(region->region_number()); size_t skip_bitmap_delta = BrooksPointer::word_size() + 1; size_t skip_objsize_delta = BrooksPointer::word_size() /* + actual obj.size() below */; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp @@ -512,23 +512,26 @@ reset_alloc_metadata(); + ShenandoahMarkingContext* const compl_ctx = _heap->complete_marking_context(); + ShenandoahMarkingContext* const next_ctx = _heap->next_marking_context(); + // Reset C-TAMS pointer to ensure size-based iteration, everything // in that regions is going to be new objects. if (ShenandoahRecycleClearsBitmap && !_heap->is_full_gc_in_progress()) { HeapWord* r_bottom = bottom(); - HeapWord* top = _heap->complete_marking_context()->top_at_mark_start(region_number()); + HeapWord* top = compl_ctx->top_at_mark_start(region_number()); if (top > r_bottom) { - _heap->complete_marking_context()->mark_bit_map()->clear_range_large(MemRegion(r_bottom, top)); + compl_ctx->clear_bitmap(r_bottom, top); } - assert(_heap->next_marking_context()->is_bitmap_clear_range(bottom(), end()), "must be clear"); - _heap->next_marking_context()->set_top_at_mark_start(region_number(), bottom()); + assert(next_ctx->is_bitmap_clear_range(bottom(), end()), "must be clear"); + next_ctx->set_top_at_mark_start(region_number(), bottom()); } // We can only safely reset the C-TAMS pointer if the bitmap is clear for that region. - assert(_heap->complete_marking_context()->is_bitmap_clear_range(bottom(), end()), "must be clear"); + assert(compl_ctx->is_bitmap_clear_range(bottom(), end()), "must be clear"); - _heap->complete_marking_context()->set_top_at_mark_start(region_number(), bottom()); + compl_ctx->set_top_at_mark_start(region_number(), bottom()); if (UseShenandoahMatrix) { _heap->connection_matrix()->clear_region(region_number()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeuristics.cpp @@ -156,6 +156,8 @@ size_t free = 0; size_t free_regions = 0; + ShenandoahMarkingContext* const ctx = heap->complete_marking_context(); + for (size_t i = 0; i < num_regions; i++) { ShenandoahHeapRegion* region = heap->get_region(i); @@ -181,7 +183,7 @@ // Reclaim humongous regions here, and count them as the immediate garbage #ifdef ASSERT bool reg_live = region->has_live(); - bool bm_live = heap->complete_marking_context()->is_marked(oop(region->bottom() + BrooksPointer::word_size())); + bool bm_live = ctx->is_marked(oop(region->bottom() + BrooksPointer::word_size())); assert(reg_live == bm_live, "Humongous liveness and marks should agree. Region live: %s; Bitmap live: %s; Region Live Words: " SIZE_FORMAT, BOOL_TO_STR(reg_live), BOOL_TO_STR(bm_live), region->get_live_data_words()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkCompact.cpp @@ -187,13 +187,13 @@ class ShenandoahPrepareForMarkClosure: public ShenandoahHeapRegionClosure { private: - ShenandoahHeap* const _heap; + ShenandoahMarkingContext* const _ctx; public: - ShenandoahPrepareForMarkClosure() : _heap(ShenandoahHeap::heap()) {} + ShenandoahPrepareForMarkClosure() : _ctx(ShenandoahHeap::heap()->next_marking_context()) {} bool heap_region_do(ShenandoahHeapRegion *r) { - _heap->next_marking_context()->set_top_at_mark_start(r->region_number(), r->top()); + _ctx->set_top_at_mark_start(r->region_number(), r->top()); r->clear_live_data(); r->set_concurrent_iteration_safe_limit(r->top()); return false; @@ -229,7 +229,7 @@ cm->mark_roots(ShenandoahPhaseTimings::full_gc_roots); cm->shared_finish_mark_from_roots(/* full_gc = */ true); - heap->swap_mark_bitmaps(); + heap->swap_mark_contexts(); if (UseShenandoahMatrix && PrintShenandoahMatrix) { LogTarget(Info, gc) lt; @@ -445,13 +445,17 @@ class ShenandoahTrashImmediateGarbageClosure: public ShenandoahHeapRegionClosure { private: ShenandoahHeap* const _heap; + ShenandoahMarkingContext* const _ctx; public: - ShenandoahTrashImmediateGarbageClosure() : _heap(ShenandoahHeap::heap()) {} + ShenandoahTrashImmediateGarbageClosure() : + _heap(ShenandoahHeap::heap()), + _ctx(ShenandoahHeap::heap()->complete_marking_context()) {} + bool heap_region_do(ShenandoahHeapRegion* r) { if (r->is_humongous_start()) { oop humongous_obj = oop(r->bottom() + BrooksPointer::word_size()); - if (!_heap->complete_marking_context()->is_marked(humongous_obj)) { + if (!_ctx->is_marked(humongous_obj)) { assert(!r->has_live(), "Region " SIZE_FORMAT " is not marked, should not have live", r->region_number()); _heap->trash_humongous_region_at(r); @@ -465,7 +469,7 @@ "Region " SIZE_FORMAT " should have live", r->region_number()); } else if (r->is_regular()) { if (!r->has_live()) { - assert(_heap->complete_marking_context()->is_bitmap_clear_range(r->bottom(), r->end()), + assert(_ctx->is_bitmap_clear_range(r->bottom(), r->end()), "Region " SIZE_FORMAT " should not have marks in bitmap", r->region_number()); r->make_trash(); } @@ -512,13 +516,14 @@ private: ShenandoahHeap* const _heap; size_t _new_obj_offset; + ShenandoahMarkingContext* const _ctx; template inline void do_oop_work(T* p) { T o = RawAccess<>::oop_load(p); if (!CompressedOops::is_null(o)) { oop obj = CompressedOops::decode_not_null(o); - assert(_heap->complete_marking_context()->is_marked(obj), "must be marked"); + assert(_ctx->is_marked(obj), "must be marked"); oop forw = oop(BrooksPointer::get_raw(obj)); RawAccess::oop_store(p, forw); if (MATRIX && UseShenandoahMatrix) { @@ -538,7 +543,10 @@ } public: - ShenandoahAdjustPointersClosure() : _heap(ShenandoahHeap::heap()), _new_obj_offset(SIZE_MAX) {} + ShenandoahAdjustPointersClosure() : + _heap(ShenandoahHeap::heap()), + _new_obj_offset(SIZE_MAX), + _ctx(ShenandoahHeap::heap()->complete_marking_context()) {} void do_oop(oop* p) { do_oop_work(p); } void do_oop(narrowOop* p) { do_oop_work(p); } @@ -839,14 +847,15 @@ void work(uint worker_id) { ShenandoahHeapRegion* region = _regions.next(); ShenandoahHeap* heap = ShenandoahHeap::heap(); + ShenandoahMarkingContext* const ctx = heap->complete_marking_context(); while (region != NULL) { if (heap->is_bitmap_slice_committed(region) && !region->is_pinned()) { HeapWord* bottom = region->bottom(); - HeapWord* top = heap->complete_marking_context()->top_at_mark_start(region->region_number()); + HeapWord* top = ctx->top_at_mark_start(region->region_number()); if (top > bottom && region->has_live()) { - heap->complete_marking_context()->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + ctx->clear_bitmap(bottom, top); } - assert(heap->complete_marking_context()->is_bitmap_clear_range(bottom, region->end()), "must be clear"); + assert(ctx->is_bitmap_clear_range(bottom, region->end()), "must be clear"); } region = _regions.next(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp @@ -58,3 +58,6 @@ return _top_at_mark_starts_base[region_number]; } +void ShenandoahMarkingContext::clear_bitmap(HeapWord* start, HeapWord* end) { + _mark_bit_map.clear_range_large(MemRegion(start, end)); +} diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.hpp @@ -59,6 +59,8 @@ HeapWord* top_at_mark_start(size_t region_number) const; void set_top_at_mark_start(size_t region_number, HeapWord* tams); + void clear_bitmap(HeapWord* start, HeapWord* end); + bool is_bitmap_clear() const; bool is_bitmap_clear_range(HeapWord* start, HeapWord* end) const; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp b/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahStringDedup.cpp @@ -106,13 +106,13 @@ class ShenandoahIsMarkedNextClosure : public BoolObjectClosure { private: - ShenandoahHeap* const _heap; + ShenandoahMarkingContext* const _mark_context; public: - ShenandoahIsMarkedNextClosure() : _heap(ShenandoahHeap::heap()) { } + ShenandoahIsMarkedNextClosure() : _mark_context(ShenandoahHeap::heap()->next_marking_context()) { } bool do_object_b(oop obj) { - return _heap->next_marking_context()->is_marked(obj); + return _mark_context->is_marked(obj); } }; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp @@ -337,17 +337,17 @@ ShenandoahHeap* heap = ShenandoahHeap::heap(); size_t num_regions = heap->num_regions(); ShenandoahConnectionMatrix* matrix = _heap->connection_matrix(); - + ShenandoahMarkingContext* const ctx = _heap->next_marking_context(); for (size_t i = 0; i < num_regions; i++) { ShenandoahHeapRegion* region = heap->get_region(i); if (heap->is_bitmap_slice_committed(region)) { if (_traversal_set.is_in(i)) { - heap->next_marking_context()->set_top_at_mark_start(region->region_number(), region->top()); + ctx->set_top_at_mark_start(region->region_number(), region->top()); region->clear_live_data(); - assert(heap->next_marking_context()->is_bitmap_clear_range(region->bottom(), region->end()), "bitmap for traversal regions must be cleared"); + assert(ctx->is_bitmap_clear_range(region->bottom(), region->end()), "bitmap for traversal regions must be cleared"); } else { // Everything outside the traversal set is always considered live. - heap->next_marking_context()->set_top_at_mark_start(region->region_number(), region->bottom()); + ctx->set_top_at_mark_start(region->region_number(), region->bottom()); } if (_root_regions.is_in(i)) { assert(!region->in_collection_set(), "roots must not overlap with cset"); @@ -711,16 +711,17 @@ ShenandoahHeapRegionSet* traversal_regions = traversal_set(); ShenandoahFreeSet* free_regions = _heap->free_set(); + ShenandoahMarkingContext* const ctx = _heap->next_marking_context(); free_regions->clear(); for (size_t i = 0; i < num_regions; i++) { ShenandoahHeapRegion* r = _heap->get_region(i); - bool not_allocated = _heap->next_marking_context()->top_at_mark_start(r->region_number()) == r->top(); + bool not_allocated = ctx->top_at_mark_start(r->region_number()) == r->top(); bool candidate = traversal_regions->is_in(r) && !r->has_live() && not_allocated; if (r->is_humongous_start() && candidate) { // Trash humongous. HeapWord* humongous_obj = r->bottom() + BrooksPointer::word_size(); - assert(!_heap->next_marking_context()->is_marked(oop(humongous_obj)), "must not be marked"); + assert(!ctx->is_marked(oop(humongous_obj)), "must not be marked"); r->make_trash(); while (i + 1 < num_regions && _heap->get_region(i + 1)->is_humongous_continuation()) { i++;