--- old/src/share/vm/gc/shenandoah/shenandoahBarrierSet.cpp 2017-10-05 21:07:57.380133999 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahBarrierSet.cpp 2017-10-05 21:07:57.256133697 +0200 @@ -411,15 +411,13 @@ if (p == NULL) return; if (heap->in_collection_set(p) && ! heap->cancelled_concgc()) { - tty->print_cr("oop = "PTR_FORMAT", resolved: "PTR_FORMAT", marked-next %s, marked-complete: %s", + tty->print_cr("oop = "PTR_FORMAT", resolved: "PTR_FORMAT", marked %s", p2i(p), p2i(read_barrier(p)), - BOOL_TO_STR(heap->is_marked_next(p)), - BOOL_TO_STR(heap->is_marked_complete(p))); + BOOL_TO_STR(heap->is_marked(p))); tty->print_cr("in_cset: %s", BOOL_TO_STR(heap->in_collection_set(p))); heap->heap_region_containing((HeapWord*) p)->print(); - tty->print_cr("top-at-mark-start: %p", heap->next_top_at_mark_start((HeapWord*) p)); - tty->print_cr("top-at-prev-mark-start: %p", heap->complete_top_at_mark_start((HeapWord*) p)); + tty->print_cr("top-at-mark-start: %p", heap->top_at_mark_start((HeapWord*) p)); tty->print_cr("marking: %s, evacuating: %s", BOOL_TO_STR(heap->concurrent_mark_in_progress()), BOOL_TO_STR(heap->is_evacuation_in_progress())); assert(false, "We should have fixed this earlier"); } --- old/src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp 2017-10-05 21:08:00.293141094 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahCollectorPolicy.cpp 2017-10-05 21:08:00.167140787 +0200 @@ -350,7 +350,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->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()); --- old/src/share/vm/gc/shenandoah/shenandoahConcurrentMark.inline.hpp 2017-10-05 21:08:00.761142234 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahConcurrentMark.inline.hpp 2017-10-05 21:08:00.647141956 +0200 @@ -41,7 +41,7 @@ || oopDesc::bs()->is_safe(obj), "we don't want to mark objects in from-space"); assert(_heap->is_in(obj), "referenced objects must be in the heap. No?"); - assert(_heap->is_marked_next(obj), "only marked objects on task queue"); + assert(_heap->is_marked(obj), "only marked objects on task queue"); if (task->is_not_chunked()) { if (COUNT_LIVENESS) count_liveness(live_data, obj); @@ -240,14 +240,14 @@ assert(heap->is_in(obj), "We shouldn't be calling this on objects not in the heap: " PTR_FORMAT, p2i(obj)); assert(oopDesc::bs()->is_safe(obj), "Only mark objects in from-space"); - if (heap->mark_next(obj)) { + if (heap->mark(obj)) { log_develop_trace(gc, marking)("Marked obj: " PTR_FORMAT, p2i((HeapWord*) obj)); bool pushed = q->push(ShenandoahMarkTask(obj)); assert(pushed, "overflow queue should always succeed pushing"); } else { log_develop_trace(gc, marking)("Failed to mark obj (already marked): " PTR_FORMAT, p2i((HeapWord*) obj)); - assert(heap->is_marked_next(obj), "Consistency: should be marked."); + assert(heap->is_marked(obj), "Consistency: should be marked."); } } } --- old/src/share/vm/gc/shenandoah/shenandoahConcurrentThread.cpp 2017-10-05 21:08:01.237143393 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahConcurrentThread.cpp 2017-10-05 21:08:01.128143128 +0200 @@ -340,7 +340,7 @@ ShenandoahGCPhase phase_reset(ShenandoahPhaseTimings::conc_cleanup_reset_bitmaps); WorkGang *workers = heap->workers(); ShenandoahPushWorkerScope scope(workers, ConcGCThreads); - heap->reset_next_mark_bitmap(workers); + heap->reset_mark_bitmap(workers); } } --- old/src/share/vm/gc/shenandoah/shenandoahHeap.cpp 2017-10-05 21:08:01.703144528 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahHeap.cpp 2017-10-05 21:08:01.592144258 +0200 @@ -82,11 +82,10 @@ ShenandoahHeapRegionSet* _regions; const size_t _bitmap_size; const size_t _page_size; - char* _bitmap0_base; - char* _bitmap1_base; + char* _bitmap_base; public: ShenandoahPretouchTask(ShenandoahHeapRegionSet* regions, - char* bitmap0_base, char* bitmap1_base, size_t bitmap_size, + char* bitmap_base, size_t bitmap_size, size_t page_size) : AbstractGangTask("Shenandoah PreTouch", Universe::is_fully_initialized() ? GCId::current_raw() : @@ -94,8 +93,7 @@ // no GC cycle that this task can be // associated with. GCId::undefined()), - _bitmap0_base(bitmap0_base), - _bitmap1_base(bitmap1_base), + _bitmap_base(bitmap_base), _regions(regions), _bitmap_size(bitmap_size), _page_size(page_size) { @@ -114,12 +112,8 @@ assert (end <= _bitmap_size, "end is sane: " SIZE_FORMAT " < " SIZE_FORMAT, end, _bitmap_size); log_trace(gc, heap)("Pretouch bitmap under region " SIZE_FORMAT ": " PTR_FORMAT " -> " PTR_FORMAT, - r->region_number(), p2i(_bitmap0_base + start), p2i(_bitmap0_base + end)); - os::pretouch_memory(_bitmap0_base + start, _bitmap0_base + end, _page_size); - - log_trace(gc, heap)("Pretouch bitmap under region " SIZE_FORMAT ": " PTR_FORMAT " -> " PTR_FORMAT, - r->region_number(), p2i(_bitmap1_base + start), p2i(_bitmap1_base + end)); - os::pretouch_memory(_bitmap1_base + start, _bitmap1_base + end, _page_size); + r->region_number(), p2i(_bitmap_base + start), p2i(_bitmap_base + end)); + os::pretouch_memory(_bitmap_base + start, _bitmap_base + end, _page_size); r = _regions->claim_next(); } @@ -171,13 +165,10 @@ _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 - + _top_at_mark_starts_base = NEW_C_HEAP_ARRAY(HeapWord*, _num_regions, mtGC); + _top_at_mark_starts = _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()); { ShenandoahHeapLocker locker(lock()); @@ -188,8 +179,7 @@ i, i < num_committed_regions); - _complete_top_at_mark_starts_base[i] = r->bottom(); - _next_top_at_mark_starts_base[i] = r->bottom(); + _top_at_mark_starts_base[i] = r->bottom(); // Add to ordered regions first. // We use the active size of ordered regions as the number of active regions in heap, @@ -244,13 +234,9 @@ size_t bitmap_page_size = UseLargePages && (bitmap_bytes_per_region >= (size_t)os::large_page_size()) ? (size_t)os::large_page_size() : (size_t)os::vm_page_size(); - ReservedSpace bitmap0(_bitmap_size, bitmap_page_size); - MemTracker::record_virtual_memory_type(bitmap0.base(), mtGC); - _bitmap0_region = MemRegion((HeapWord*) bitmap0.base(), bitmap0.size() / HeapWordSize); - - ReservedSpace bitmap1(_bitmap_size, bitmap_page_size); - MemTracker::record_virtual_memory_type(bitmap1.base(), mtGC); - _bitmap1_region = MemRegion((HeapWord*) bitmap1.base(), bitmap1.size() / HeapWordSize); + ReservedSpace bitmap(_bitmap_size, bitmap_page_size); + MemTracker::record_virtual_memory_type(bitmap.base(), mtGC); + _bitmap_region = MemRegion((HeapWord*) bitmap.base(), bitmap.size() / HeapWordSize); { ShenandoahHeapLocker locker(lock()); @@ -283,15 +269,12 @@ log_info(gc, heap)("Parallel pretouch " SIZE_FORMAT " regions with " SIZE_FORMAT " byte pages", _ordered_regions->count(), page_size); - ShenandoahPretouchTask cl(_ordered_regions, bitmap0.base(), bitmap1.base(), _bitmap_size, page_size); + ShenandoahPretouchTask cl(_ordered_regions, bitmap.base(), _bitmap_size, page_size); _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; + __mark_bit_map.initialize(_heap_region, _bitmap_region); + _mark_bit_map = & __mark_bit_map; if (UseShenandoahMatrix) { _connection_matrix = new ShenandoahConnectionMatrix(_num_regions); @@ -337,16 +320,15 @@ _used_start_gc(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(), + _top_at_mark_starts(NULL), + _top_at_mark_starts_base(NULL), + __mark_bit_map(), + _mark_bit_map(NULL), _connection_matrix(NULL), _cancelled_concgc(0), _need_update_refs(false), - _need_reset_bitmaps(false), + _need_reset_bitmap(false), + _bitmap_valid(true), _verifier(NULL), _heap_lock(0), _used_at_last_gc(0), @@ -386,12 +368,12 @@ } } -class ShenandoahResetNextBitmapTask : public AbstractGangTask { +class ShenandoahResetBitmapTask : public AbstractGangTask { private: ShenandoahHeapRegionSet* _regions; public: - ShenandoahResetNextBitmapTask(ShenandoahHeapRegionSet* regions) : + ShenandoahResetBitmapTask(ShenandoahHeapRegionSet* regions) : AbstractGangTask("Parallel Reset Bitmap Task"), _regions(regions) { _regions->clear_current_index(); @@ -403,75 +385,36 @@ while (region != NULL) { if (region->is_committed()) { HeapWord* bottom = region->bottom(); - HeapWord* top = heap->next_top_at_mark_start(region->bottom()); + HeapWord* top = heap->top_at_mark_start(region->bottom()); if (top > bottom) { - heap->next_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + heap->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); } - assert(heap->is_next_bitmap_clear_range(bottom, region->end()), "must be clear"); + assert(heap->is_bitmap_clear_range(bottom, region->end()), "must be clear"); } region = _regions->claim_next(); } } }; -void ShenandoahHeap::reset_next_mark_bitmap(WorkGang* workers) { +void ShenandoahHeap::reset_mark_bitmap(WorkGang* workers) { assert_gc_workers(workers->active_workers()); - ShenandoahResetNextBitmapTask task = ShenandoahResetNextBitmapTask(_ordered_regions); + ShenandoahResetBitmapTask task = ShenandoahResetBitmapTask(_ordered_regions); workers->run_task(&task); } -class ShenandoahResetCompleteBitmapTask : public AbstractGangTask { -private: - ShenandoahHeapRegionSet* _regions; - -public: - ShenandoahResetCompleteBitmapTask(ShenandoahHeapRegionSet* regions) : - AbstractGangTask("Parallel Reset Bitmap Task"), - _regions(regions) { - _regions->clear_current_index(); - } - - void work(uint worker_id) { - ShenandoahHeapRegion* region = _regions->claim_next(); - ShenandoahHeap* heap = ShenandoahHeap::heap(); - while (region != NULL) { - if (region->is_committed()) { - HeapWord* bottom = region->bottom(); - HeapWord* top = heap->complete_top_at_mark_start(region->bottom()); - if (top > bottom) { - heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); - } - assert(heap->is_complete_bitmap_clear_range(bottom, region->end()), "must be clear"); - } - region = _regions->claim_next(); - } - } -}; - -void ShenandoahHeap::reset_complete_mark_bitmap(WorkGang* workers) { - assert_gc_workers(workers->active_workers()); - - ShenandoahResetCompleteBitmapTask task = ShenandoahResetCompleteBitmapTask(_ordered_regions); - workers->run_task(&task); -} - -bool ShenandoahHeap::is_next_bitmap_clear() { +bool ShenandoahHeap::is_bitmap_clear() { for (size_t idx = 0; idx < _num_regions; idx++) { ShenandoahHeapRegion* r = _ordered_regions->get(idx); - if (r->is_committed() && !is_next_bitmap_clear_range(r->bottom(), r->end())) { + if (r->is_committed() && !is_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; +bool ShenandoahHeap::is_bitmap_clear_range(HeapWord* start, HeapWord* end) { + return _mark_bit_map->getNextMarkedWordAddress(start, end) == end; } void ShenandoahHeap::print_on(outputStream* st) const { @@ -787,8 +730,8 @@ if (! oopDesc::is_null(o)) { oop obj = oopDesc::decode_heap_oop_not_null(o); if (_heap->in_collection_set(obj)) { - assert(_heap->is_marked_complete(obj), "only evacuate marked objects %d %d", - _heap->is_marked_complete(obj), _heap->is_marked_complete(ShenandoahBarrierSet::resolve_oop_static_not_null(obj))); + assert(_heap->is_marked(obj), "only evacuate marked objects %d %d", + _heap->is_marked(obj), _heap->is_marked(ShenandoahBarrierSet::resolve_oop_static_not_null(obj))); oop resolved = ShenandoahBarrierSet::resolve_oop_static_not_null(obj); if (oopDesc::unsafe_equals(resolved, obj)) { bool evac; @@ -851,7 +794,7 @@ _heap(heap), _thread(Thread::current()) {} void do_object(oop p) { - assert(_heap->is_marked_complete(p), "expect only marked objects"); + assert(_heap->is_marked(p), "expect only marked objects"); if (oopDesc::unsafe_equals(p, ShenandoahBarrierSet::resolve_oop_static_not_null(p))) { bool evac; _heap->evacuate_object(p, _thread, evac); @@ -1454,7 +1397,7 @@ bool heap_region_do(ShenandoahHeapRegion* r) { r->clear_live_data(); - sh->set_next_top_at_mark_start(r->bottom(), r->top()); + sh->set_top_at_mark_start(r->bottom(), r->top()); return false; } }; @@ -1496,30 +1439,12 @@ } } -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; -} - - void ShenandoahHeap::stop_concurrent_marking() { assert(concurrent_mark_in_progress(), "How else could we get here?"); if (! cancelled_concgc()) { // If we needed to update refs, and concurrent marking has been cancelled, // we need to finish updating references. set_need_update_refs(false); - swap_mark_bitmaps(); } set_concurrent_mark_in_progress(false); @@ -1601,7 +1526,7 @@ } #endif assert(!oopDesc::is_null(obj), "null"); - return _heap->is_marked_next(obj); + return _heap->is_marked(obj); } ShenandoahIsAliveClosure::ShenandoahIsAliveClosure() : @@ -1612,7 +1537,7 @@ assert(_heap != NULL, "sanity"); assert(!oopDesc::is_null(obj), "null"); assert(oopDesc::unsafe_equals(obj, ShenandoahBarrierSet::resolve_oop_static_not_null(obj)), "only query to-space"); - return _heap->is_marked_next(obj); + return _heap->is_marked(obj); } BoolObjectClosure* ShenandoahHeap::is_alive_closure() { @@ -1799,12 +1724,8 @@ 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; +MarkBitMap* ShenandoahHeap::mark_bit_map() { + return _mark_bit_map; } void ShenandoahHeap::add_free_region(ShenandoahHeapRegion* r) { @@ -1838,24 +1759,14 @@ _bytes_allocated_since_cm = bytes; } -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) { +void ShenandoahHeap::set_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; + _top_at_mark_starts[index] = addr; } -HeapWord* ShenandoahHeap::complete_top_at_mark_start(HeapWord* region_base) { +HeapWord* ShenandoahHeap::top_at_mark_start(HeapWord* region_base) { uintx index = ((uintx) region_base) >> ShenandoahHeapRegion::region_size_bytes_shift(); - return _complete_top_at_mark_starts[index]; + return _top_at_mark_starts[index]; } void ShenandoahHeap::set_full_gc_in_progress(bool in_progress) { @@ -1985,9 +1896,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->top_at_mark_start(r->bottom()); if (top > bottom) { - _heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + _heap->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); } } else { if (r->is_active()) { @@ -2189,10 +2100,7 @@ bool ShenandoahHeap::commit_bitmaps(ShenandoahHeapRegion* r) { size_t len = _bitmap_words_per_region * HeapWordSize; size_t off = r->region_number() * _bitmap_words_per_region; - if (!os::commit_memory((char*)(_bitmap0_region.start() + off), len, false)) { - return false; - } - if (!os::commit_memory((char*)(_bitmap1_region.start() + off), len, false)) { + if (!os::commit_memory((char*)(_bitmap_region.start() + off), len, false)) { return false; } return true; @@ -2201,10 +2109,7 @@ bool ShenandoahHeap::uncommit_bitmaps(ShenandoahHeapRegion* r) { size_t len = _bitmap_words_per_region * HeapWordSize; size_t off = r->region_number() * _bitmap_words_per_region; - if (!os::uncommit_memory((char*)(_bitmap0_region.start() + off), len)) { - return false; - } - if (!os::uncommit_memory((char*)(_bitmap1_region.start() + off), len)) { + if (!os::uncommit_memory((char*)(_bitmap_region.start() + off), len)) { return false; } return true; --- old/src/share/vm/gc/shenandoah/shenandoahHeap.hpp 2017-10-05 21:08:02.206145753 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahHeap.hpp 2017-10-05 21:08:02.093145478 +0200 @@ -135,8 +135,7 @@ size_t _bitmap_size; size_t _bitmap_words_per_region; MemRegion _heap_region; - MemRegion _bitmap0_region; - MemRegion _bitmap1_region; + MemRegion _bitmap_region; // Sortable array of regions ShenandoahHeapRegionSet* _ordered_regions; @@ -165,16 +164,12 @@ 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 __mark_bit_map; + MarkBitMap* _mark_bit_map; + bool _bitmap_valid; - 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; + HeapWord** _top_at_mark_starts; + HeapWord** _top_at_mark_starts_base; volatile jbyte _cancelled_concgc; @@ -190,7 +185,7 @@ unsigned int _evacuation_in_progress; bool _need_update_refs; - bool _need_reset_bitmaps; + bool _need_reset_bitmap; ReferenceProcessor* _ref_processor; @@ -340,13 +335,9 @@ 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); + inline bool allocated_after_mark_start(HeapWord* addr) const; + void set_top_at_mark_start(HeapWord* region_base, HeapWord* addr); + HeapWord* 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 @@ -378,17 +369,16 @@ size_t garbage(); - void reset_next_mark_bitmap(WorkGang* gang); - void reset_complete_mark_bitmap(WorkGang* gang); + void reset_mark_bitmap(WorkGang* gang); + + MarkBitMap* mark_bit_map(); + inline bool is_marked(oop obj) const; + inline bool mark(oop obj) const; + bool is_bitmap_clear(); + bool is_bitmap_clear_range(HeapWord* start, HeapWord* end); - 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); + bool is_bitmap_valid() const { return _bitmap_valid; } + void set_bitmap_valid(bool valid) { _bitmap_valid = valid; } bool commit_bitmaps(ShenandoahHeapRegion* r); bool uncommit_bitmaps(ShenandoahHeapRegion* r); @@ -454,8 +444,6 @@ GCTimer* gc_timer() const; - void swap_mark_bitmaps(); - void cancel_concgc(GCCause::Cause cause); void cancel_concgc(ShenandoahCancelCause cause); @@ -502,7 +490,7 @@ ShenandoahConcurrentThread* concurrent_thread() { return _concurrent_gc_thread; } - inline bool mark_next_no_checks(oop obj) const; + inline bool mark_no_checks(oop obj) const; public: inline oop atomic_compare_exchange_oop(oop n, narrowOop* addr, oop c); --- old/src/share/vm/gc/shenandoah/shenandoahHeap.inline.hpp 2017-10-05 21:08:02.977147631 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahHeap.inline.hpp 2017-10-05 21:08:02.866147360 +0200 @@ -63,7 +63,7 @@ * 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 { +inline bool ShenandoahHeap::mark(oop obj) const { #ifdef ASSERT if (! oopDesc::unsafe_equals(obj, oopDesc::bs()->read_barrier(obj))) { tty->print_cr("heap region containing obj:"); @@ -76,22 +76,17 @@ #endif assert(oopDesc::unsafe_equals(obj, oopDesc::bs()->read_barrier(obj)), "only mark forwarded copy of objects"); - return mark_next_no_checks(obj); + return mark_no_checks(obj); } -inline bool ShenandoahHeap::mark_next_no_checks(oop obj) const { +inline bool ShenandoahHeap::mark_no_checks(oop obj) const { HeapWord* addr = (HeapWord*) obj; - return (! allocated_after_next_mark_start(addr)) && _next_mark_bit_map->parMark(addr); + return (! allocated_after_mark_start(addr)) && _mark_bit_map->parMark(addr); } -inline bool ShenandoahHeap::is_marked_next(oop obj) const { +inline bool ShenandoahHeap::is_marked(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); + return allocated_after_mark_start(addr) || _mark_bit_map->isMarked(addr); } inline bool ShenandoahHeap::need_update_refs() const { @@ -397,7 +392,7 @@ } inline bool ShenandoahHeap::requires_marking(const void* entry) const { - return ! is_marked_next(oop(entry)); + return ! is_marked(oop(entry)); } bool ShenandoahHeap::region_in_collection_set(size_t region_index) const { @@ -438,16 +433,9 @@ return (address) &(ShenandoahHeap::heap()->_evacuation_in_progress); } -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 { +inline bool ShenandoahHeap::allocated_after_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]; + 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; } @@ -467,15 +455,16 @@ 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"); + assert(is_bitmap_valid(), "only try this with complete marking bitmap"); - MarkBitMap* mark_bit_map = _complete_mark_bit_map; - HeapWord* top_at_mark_start = complete_top_at_mark_start(region->bottom()); + MarkBitMap* mark_bit_map = _mark_bit_map; + HeapWord* tams = top_at_mark_start(region->bottom()); size_t skip_bitmap_delta = BrooksPointer::word_size() + 1; size_t skip_objsize_delta = BrooksPointer::word_size() /* + actual obj.size() below */; HeapWord* start = region->bottom() + BrooksPointer::word_size(); - HeapWord* end = MIN2(top_at_mark_start + BrooksPointer::word_size(), region->end()); + HeapWord* end = MIN2(tams + BrooksPointer::word_size(), region->end()); HeapWord* addr = mark_bit_map->getNextMarkedWordAddress(start, end); intx dist = ShenandoahMarkScanPrefetch; @@ -503,7 +492,7 @@ Prefetch::read(addr, BrooksPointer::byte_offset()); oop obj = oop(addr); slots[avail++] = obj; - if (addr < top_at_mark_start) { + if (addr < tams) { addr += skip_bitmap_delta; addr = mark_bit_map->getNextMarkedWordAddress(addr, end); } else { @@ -532,7 +521,7 @@ int size = obj->size(); do_marked_object(mark_bit_map, cl, obj); addr += size + skip_objsize_delta; - if (addr < top_at_mark_start) { + if (addr < tams) { addr = mark_bit_map->getNextMarkedWordAddress(addr, end); } } @@ -544,8 +533,8 @@ assert(!oopDesc::is_null(obj), "sanity"); assert(oopDesc::is_oop(obj), "sanity"); assert(is_in(obj), "sanity"); - assert(bitmap == _complete_mark_bit_map, "only iterate completed mark bitmap"); - assert(is_marked_complete(obj), "object expected to be marked"); + assert(bitmap == _mark_bit_map, "only iterate completed mark bitmap"); + assert(is_marked(obj), "object expected to be marked"); cl->do_object(obj); } --- old/src/share/vm/gc/shenandoah/shenandoahHeapRegion.cpp 2017-10-05 21:08:03.443148766 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahHeapRegion.cpp 2017-10-05 21:08:03.330148491 +0200 @@ -387,9 +387,8 @@ } st->print("|CP " SIZE_FORMAT_W(3), _critical_pins); - st->print_cr("|TAMS " PTR_FORMAT ", " PTR_FORMAT "|", - p2i(ShenandoahHeap::heap()->complete_top_at_mark_start(_bottom)), - p2i(ShenandoahHeap::heap()->next_top_at_mark_start(_bottom))); + st->print_cr("|TAMS " PTR_FORMAT "|", + p2i(ShenandoahHeap::heap()->top_at_mark_start(_bottom))); } void ShenandoahHeapRegion::object_iterate_interruptible(ObjectClosure* blk, bool allow_cancel) { @@ -482,9 +481,9 @@ // Reset C-TAMS pointer to ensure size-based iteration, everything // in that regions is going to be new objects. - _heap->set_complete_top_at_mark_start(bottom(), bottom()); + _heap->set_top_at_mark_start(bottom(), 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->is_bitmap_clear_range(bottom(), end()), "must be clear"); make_empty_committed(); } --- old/src/share/vm/gc/shenandoah/shenandoahMarkCompact.cpp 2017-10-05 21:08:04.494151326 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahMarkCompact.cpp 2017-10-05 21:08:04.382151053 +0200 @@ -78,7 +78,7 @@ ShenandoahClearRegionStatusClosure() : _heap(ShenandoahHeap::heap()) {} bool heap_region_do(ShenandoahHeapRegion *r) { - _heap->set_next_top_at_mark_start(r->bottom(), r->top()); + _heap->set_top_at_mark_start(r->bottom(), r->top()); r->clear_live_data(); r->set_concurrent_iteration_safe_limit(r->top()); return false; @@ -147,8 +147,8 @@ assert(!heap->is_evacuation_in_progress(), "sanity"); // c. Reset the bitmaps for new marking - heap->reset_next_mark_bitmap(heap->workers()); - assert(heap->is_next_bitmap_clear(), "sanity"); + heap->reset_mark_bitmap(heap->workers()); + assert(heap->is_bitmap_clear(), "sanity"); // d. Abandon reference discovery and clear all discovered references. ReferenceProcessor* rp = heap->ref_processor(); @@ -295,8 +295,6 @@ cm->mark_roots(ShenandoahPhaseTimings::full_gc_roots); cm->shared_finish_mark_from_roots(/* full_gc = */ true); - _heap->swap_mark_bitmaps(); - if (UseShenandoahMatrix && PrintShenandoahMatrix) { LogTarget(Info, gc) lt; LogStream ls(lt); @@ -318,6 +316,7 @@ // objects. _heap->verify(VerifyOption_G1UseMarkWord); } + _heap->set_bitmap_valid(true); } class ShenandoahMCReclaimHumongousRegionClosure : public ShenandoahHeapRegionClosure { @@ -330,7 +329,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->is_marked(humongous_obj)) { _heap->trash_humongous_region_at(r); } } @@ -371,8 +370,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->is_marked(p), "must be marked"); + assert(! _heap->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()) { // Object doesn't fit. Pick next to-region and start compacting there. @@ -497,7 +496,7 @@ T o = oopDesc::load_heap_oop(p); if (! oopDesc::is_null(o)) { oop obj = oopDesc::decode_heap_oop_not_null(o); - assert(_heap->is_marked_complete(obj), "must be marked"); + assert(_heap->is_marked(obj), "must be marked"); oop forw = oop(BrooksPointer::get_raw(obj)); oopDesc::encode_store_heap_oop(p, forw); if (UseShenandoahMatrix) { @@ -536,7 +535,7 @@ _heap(ShenandoahHeap::heap()) { } void do_object(oop p) { - assert(_heap->is_marked_complete(p), "must be marked"); + assert(_heap->is_marked(p), "must be marked"); HeapWord* forw = BrooksPointer::get_raw(p); _cl.set_new_obj_offset(pointer_delta((HeapWord*) p, forw)); p->oop_iterate(&_cl); @@ -627,7 +626,7 @@ _str_dedup(ShenandoahStringDedup::is_enabled()), _worker_id(worker_id) { } void do_object(oop p) { - assert(_heap->is_marked_complete(p), "must be marked"); + assert(_heap->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; @@ -685,7 +684,7 @@ // Need to reset the complete-top-at-mark-start pointer here because // the complete marking bitmap is no longer valid. This ensures // size-based iteration in marked_object_iterate(). - _heap->set_complete_top_at_mark_start(r->bottom(), r->bottom()); + _heap->set_top_at_mark_start(r->bottom(), r->bottom()); size_t live = r->used(); @@ -732,7 +731,7 @@ // Reset complete bitmap. We're about to reset the complete-top-at-mark-start pointer // and must ensure the bitmap is in sync. - heap->reset_complete_mark_bitmap(heap->workers()); + heap->reset_mark_bitmap(heap->workers()); { ShenandoahHeapLocker lock(heap->lock()); @@ -745,9 +744,6 @@ heap->collection_set()->clear(); heap->clear_cancelled_concgc(); - // Also clear the next bitmap in preparation for next marking. - heap->reset_next_mark_bitmap(heap->workers()); - for (uint i = 0; i < heap->max_workers(); i++) { delete copy_queues[i]; } --- old/src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp 2017-10-05 21:08:05.915154787 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp 2017-10-05 21:08:05.803154514 +0200 @@ -159,9 +159,9 @@ ShenandoahHeapRegion* r = cset->claim_next(); while (r != NULL) { HeapWord* bottom = r->bottom(); - HeapWord* top = _heap->complete_top_at_mark_start(r->bottom()); + HeapWord* top = _heap->top_at_mark_start(r->bottom()); if (top > bottom) { - _heap->complete_mark_bit_map()->clear_range_large(MemRegion(bottom, top)); + _heap->mark_bit_map()->clear_range_large(MemRegion(bottom, top)); } r = cset->claim_next(); } --- old/src/share/vm/gc/shenandoah/shenandoahPrinter.cpp 2017-10-05 21:08:06.456156104 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahPrinter.cpp 2017-10-05 21:08:06.341155824 +0200 @@ -46,7 +46,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()->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)", @@ -79,7 +79,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()->is_marked(p)), p->klass()->internal_name(), p2i(p->klass())); ShenandoahPrintAllRefsOopClosure cl(_prefix); p->oop_iterate(&cl); --- old/src/share/vm/gc/shenandoah/shenandoahStringDedup.cpp 2017-10-05 21:08:06.967157349 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahStringDedup.cpp 2017-10-05 21:08:06.861157090 +0200 @@ -49,7 +49,7 @@ bool do_object_b(oop obj) { assert(!oopDesc::is_null(obj), "null"); - return _heap->is_marked_complete(obj); + return _heap->is_marked(obj); } }; --- old/src/share/vm/gc/shenandoah/shenandoahVerifier.cpp 2017-10-05 21:08:07.419158449 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahVerifier.cpp 2017-10-05 21:08:07.309158182 +0200 @@ -59,10 +59,8 @@ 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 mark start\n", _heap->allocated_after_mark_start((HeapWord *) obj) ? "" : "not"); + msg.append(" %3s marked \n", _heap->is_marked(obj) ? "" : "not"); msg.append(" %3s in collection set\n", _heap->in_collection_set(obj) ? "" : "not"); msg.append(" region: %s", ss.as_string()); } @@ -306,12 +304,8 @@ case ShenandoahVerifier::_verify_marked_disable: // skip break; - case ShenandoahVerifier::_verify_marked_next: - verify(_safe_all, obj, _heap->is_marked_next(obj), - "Must be marked in next bitmap"); - break; - case ShenandoahVerifier::_verify_marked_complete: - verify(_safe_all, obj, _heap->is_marked_complete(obj), + case ShenandoahVerifier::_verify_marked: + verify(_safe_all, obj, _heap->is_marked(obj), "Must be marked in complete bitmap"); break; default: @@ -488,11 +482,11 @@ 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->top_at_mark_start(r->bottom()), "Region top should not be less than bottom"); - verify(r, _heap->complete_top_at_mark_start(r->bottom()) <= r->top(), - "Complete TAMS should not be larger than top"); + verify(r, _heap->top_at_mark_start(r->bottom()) <= r->top(), + "TAMS should not be larger than top"); verify(r, r->get_live_data_bytes() <= r->capacity(), "Live data cannot be larger than capacity"); @@ -639,7 +633,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->is_marked((oop)obj)) { verify_and_follow(obj, stack, cl, &processed); } Atomic::add(processed, &_processed); @@ -647,8 +641,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->mark_bit_map(); + HeapWord* tams = _heap->top_at_mark_start(r->bottom()); // Bitmaps, before TAMS if (tams > r->bottom()) { @@ -768,18 +762,18 @@ // version size_t count_marked = 0; - if (ShenandoahVerifyLevel >= 4 && marked == _verify_marked_complete) { + if (ShenandoahVerifyLevel >= 4 && marked == _verify_marked) { ShenandoahVerifierMarkedRegionTask task(_heap->regions(), _verification_bit_map, ld, label, options); _heap->workers()->run_task(&task); count_marked = task.processed(); } else { - guarantee(ShenandoahVerifyLevel < 4 || marked == _verify_marked_next || marked == _verify_marked_disable, "Should be"); + guarantee(ShenandoahVerifyLevel < 4 || marked == _verify_marked_disable, "Should be"); } // Step 4. Verify accumulated liveness data, if needed. Only reliable if verification level includes // marked objects. - if (ShenandoahVerifyLevel >= 4 && marked == _verify_marked_complete && liveness == _verify_liveness_complete) { + if (ShenandoahVerifyLevel >= 4 && marked == _verify_marked && liveness == _verify_liveness_complete) { ShenandoahHeapRegionSet* set = _heap->regions(); for (size_t i = 0; i < _heap->num_regions(); i++) { ShenandoahHeapRegion* r = set->get(i); @@ -853,7 +847,7 @@ verify_at_safepoint( "After Mark", _verify_forwarded_none, // no forwarded references - _verify_marked_complete, // bitmaps as precise as we can get + _verify_marked, // bitmaps as precise as we can get _verify_matrix_disable, // matrix might be foobared _verify_cset_none, // no references to cset anymore _verify_liveness_complete, // liveness data must be complete here @@ -867,7 +861,7 @@ verify_at_safepoint( "Before Evacuation", _verify_forwarded_none, // no forwarded references - _verify_marked_complete, // walk over marked objects too + _verify_marked, // walk over marked objects too _verify_matrix_disable, // skip, verified after mark _verify_cset_disable, // skip, verified after mark _verify_liveness_disable, // skip, verified after mark @@ -879,7 +873,7 @@ verify_at_safepoint( "After Evacuation", _verify_forwarded_allow, // objects are still forwarded - _verify_marked_complete, // bitmaps might be stale, but alloc-after-mark should be well + _verify_marked, // bitmaps might be stale, but alloc-after-mark should be well _verify_matrix_disable, // matrix is inconsistent here _verify_cset_forwarded, // all cset refs are fully forwarded _verify_liveness_disable, // no reliable liveness data anymore @@ -891,7 +885,7 @@ verify_at_safepoint( "Before Updating References", _verify_forwarded_allow, // forwarded references allowed - _verify_marked_complete, // bitmaps might be stale, but alloc-after-mark should be well + _verify_marked, // bitmaps might be stale, but alloc-after-mark should be well _verify_matrix_disable, // matrix is inconsistent here _verify_cset_forwarded, // all cset refs are fully forwarded _verify_liveness_disable, // no reliable liveness data anymore @@ -903,7 +897,7 @@ verify_at_safepoint( "After Updating References", _verify_forwarded_none, // no forwarded references - _verify_marked_complete, // bitmaps might be stale, but alloc-after-mark should be well + _verify_marked, // bitmaps might be stale, but alloc-after-mark should be well _verify_matrix_conservative, // matrix is conservatively consistent _verify_cset_none, // no cset references, all updated _verify_liveness_disable, // no reliable liveness data anymore @@ -915,7 +909,7 @@ verify_at_safepoint( "Before Partial GC", _verify_forwarded_none, // cannot have forwarded objects - _verify_marked_complete, // bitmaps might be stale, but alloc-after-mark should be well + _verify_marked, // bitmaps might be stale, but alloc-after-mark should be well _verify_matrix_conservative, // matrix is conservatively consistent _verify_cset_none, // no cset references before partial _verify_liveness_disable, // no reliable liveness data anymore @@ -927,7 +921,7 @@ verify_at_safepoint( "After Partial GC", _verify_forwarded_none, // cannot have forwarded objects - _verify_marked_complete, // bitmaps might be stale, but alloc-after-mark should be well + _verify_marked, // bitmaps might be stale, but alloc-after-mark should be well _verify_matrix_conservative, // matrix is conservatively consistent _verify_cset_none, // no cset references left after partial _verify_liveness_disable, // no reliable liveness data anymore @@ -951,7 +945,7 @@ verify_at_safepoint( "After Full GC", _verify_forwarded_none, // all objects are non-forwarded - _verify_marked_complete, // all objects are marked in complete bitmap + _verify_marked, // all objects are marked in complete bitmap _verify_matrix_conservative, // matrix is conservatively consistent _verify_cset_none, // no cset references _verify_liveness_disable, // no reliable liveness data anymore --- old/src/share/vm/gc/shenandoah/shenandoahVerifier.hpp 2017-10-05 21:08:07.914159655 +0200 +++ new/src/share/vm/gc/shenandoah/shenandoahVerifier.hpp 2017-10-05 21:08:07.805159390 +0200 @@ -90,10 +90,8 @@ _verify_marked_disable, // Objects should be marked in "next" bitmap. - _verify_marked_next, + _verify_marked, - // Objects should be marked in "complete" bitmap. - _verify_marked_complete, } VerifyMarked; typedef enum { --- old/src/share/vm/gc/shenandoah/vm_operations_shenandoah.cpp 2017-10-05 21:08:08.636161414 +0200 +++ new/src/share/vm/gc/shenandoah/vm_operations_shenandoah.cpp 2017-10-05 21:08:08.528161151 +0200 @@ -48,7 +48,9 @@ ShenandoahWorkerScope scope(workers, nworkers); - assert(sh->is_next_bitmap_clear(), "need clear marking bitmap"); + assert(sh->is_bitmap_clear(), "need clear marking bitmap"); + + sh->set_bitmap_valid(false); sh->start_concurrent_marking(); } @@ -86,6 +88,7 @@ if (! sh->cancelled_concgc()) { GCTraceTime(Info, gc) time("Pause Final Mark", sh->gc_timer(), GCCause::_no_gc, true); sh->concurrentMark()->finish_mark_from_roots(); + sh->set_bitmap_valid(true); sh->stop_concurrent_marking(); {