diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp index 5d19a6a34e3..f6733d4a923 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp @@ -89,8 +89,19 @@ bool ShenandoahBarrierSet::need_keep_alive_barrier(DecoratorSet decorators, Basi void ShenandoahBarrierSet::on_slowpath_allocation_exit(JavaThread* thread, oop new_obj) { #if COMPILER2_OR_JVMCI - assert(!ReduceInitialCardMarks || !ShenandoahCardBarrier || ShenandoahGenerationalHeap::heap()->is_in_young(new_obj), - "Allocating new object outside of young generation: " INTPTR_FORMAT, p2i(new_obj)); + if (ReduceInitialCardMarks && ShenandoahCardBarrier && !ShenandoahHeap::heap()->is_in_young(new_obj)) { + log_debug(gc)("Newly allocated object (" PTR_FORMAT ") is not in the young generation", p2i(new_obj)); + // This can happen when an object is newly allocated, but we come to a safepoint before returning + // the object. If the safepoint runs a degenerated cycle that is upgraded to a full GC, this object + // will have survived two GC cycles. If the tenuring age is very low (1), this object may be promoted. + // In this case, we have an allocated object, but it has received no stores yet. If card marking barriers + // have been elided, we could end up with an object in old holding pointers to young that won't be in + // the remembered set. The solution here is conservative, but this problem should be rare, and it will + // correct itself on subsequent cycles when the remembered set is updated. + ShenandoahGenerationalHeap::heap()->old_generation()->card_scan()->mark_range_as_dirty( + cast_from_oop(new_obj), new_obj->size() + ); + } #endif // COMPILER2_OR_JVMCI assert(thread->deferred_card_mark().is_empty(), "We don't use this"); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp index 0babeaffd3e..40eee8c342b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp @@ -74,8 +74,8 @@ void ShenandoahMarkingContext::initialize_top_at_mark_start(ShenandoahHeapRegion _top_at_mark_starts_base[idx] = bottom; _top_bitmaps[idx] = bottom; - log_debug(gc)("SMC:initialize_top_at_mark_start for Region %zu, TAMS: " PTR_FORMAT ", TopOfBitMap: " PTR_FORMAT, - r->index(), p2i(bottom), p2i(r->end())); + log_debug(gc, mark)("SMC:initialize_top_at_mark_start for Region %zu, TAMS: " PTR_FORMAT ", TopOfBitMap: " PTR_FORMAT, + r->index(), p2i(bottom), p2i(r->end())); } HeapWord* ShenandoahMarkingContext::top_bitmap(ShenandoahHeapRegion* r) { @@ -86,8 +86,8 @@ void ShenandoahMarkingContext::clear_bitmap(ShenandoahHeapRegion* r) { HeapWord* bottom = r->bottom(); HeapWord* top_bitmap = _top_bitmaps[r->index()]; - log_debug(gc)("SMC:clear_bitmap for %s Region %zu, top_bitmap: " PTR_FORMAT, - r->affiliation_name(), r->index(), p2i(top_bitmap)); + log_debug(gc, mark)("SMC:clear_bitmap for %s Region %zu, top_bitmap: " PTR_FORMAT, + r->affiliation_name(), r->index(), p2i(top_bitmap)); if (top_bitmap > bottom) { _mark_bit_map.clear_range_large(MemRegion(bottom, top_bitmap)); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp index e3ba774283c..bff4afc9ce9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.inline.hpp @@ -104,8 +104,8 @@ inline void ShenandoahMarkingContext::capture_top_at_mark_start(ShenandoahHeapRe "Region %zu, bitmap should be clear while adjusting TAMS: " PTR_FORMAT " -> " PTR_FORMAT, idx, p2i(old_tams), p2i(new_tams)); - log_debug(gc)("Capturing TAMS for %s Region %zu, was: " PTR_FORMAT ", now: " PTR_FORMAT, - r->affiliation_name(), idx, p2i(old_tams), p2i(new_tams)); + log_debug(gc, mark)("Capturing TAMS for %s Region %zu, was: " PTR_FORMAT ", now: " PTR_FORMAT, + r->affiliation_name(), idx, p2i(old_tams), p2i(new_tams)); _top_at_mark_starts_base[idx] = new_tams; _top_bitmaps[idx] = new_tams; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.cpp b/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.cpp index 23c705348c4..4a0215f15f1 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.cpp @@ -683,9 +683,9 @@ void ShenandoahScanRememberedTask::do_work(uint worker_id) { struct ShenandoahRegionChunk assignment; while (_work_list->next(&assignment)) { ShenandoahHeapRegion* region = assignment._r; - log_debug(gc)("ShenandoahScanRememberedTask::do_work(%u), processing slice of region " - "%zu at offset %zu, size: %zu", - worker_id, region->index(), assignment._chunk_offset, assignment._chunk_size); + log_debug(gc, remset)("ShenandoahScanRememberedTask::do_work(%u), processing slice of region " + "%zu at offset %zu, size: %zu", + worker_id, region->index(), assignment._chunk_offset, assignment._chunk_size); if (region->is_old()) { size_t cluster_size = CardTable::card_size_in_words() * ShenandoahCardCluster::CardsPerCluster; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.inline.hpp index ce7cda98412..919cc4f6fd7 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahScanRemembered.inline.hpp @@ -343,9 +343,9 @@ ShenandoahScanRemembered::process_region_slice(ShenandoahHeapRegion *region, siz } } - log_debug(gc)("Remembered set scan processing Region %zu, from " PTR_FORMAT " to " PTR_FORMAT ", using %s table", - region->index(), p2i(start_of_range), p2i(end_of_range), - use_write_table? "read/write (updating)": "read (marking)"); + log_debug(gc, remset)("Remembered set scan processing Region %zu, from " PTR_FORMAT " to " PTR_FORMAT ", using %s table", + region->index(), p2i(start_of_range), p2i(end_of_range), + use_write_table? "read/write (updating)": "read (marking)"); // Note that end_of_range may point to the middle of a cluster because we limit scanning to // region->top() or region->get_update_watermark(). We avoid processing past end_of_range.