Skip to content

Commit f0ac948

Browse files
author
William Kemper
committed
8380390: Shenandoah: Missing store barrier when resetting bitmaps
8386798: Shenandoah: Missing load barrier when making assertions about mark bitmap Reviewed-by: xpeng, kdnilsen Backport-of: a13dd29
1 parent 535c166 commit f0ac948

6 files changed

Lines changed: 30 additions & 23 deletions

File tree

src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "gc/shenandoah/shenandoahUtils.hpp"
3232
#include "memory/resourceArea.hpp"
3333
#include "oops/oop.inline.hpp"
34+
#include "runtime/orderAccess.hpp"
3435
#include "runtime/os.hpp"
3536
#include "utilities/vmError.hpp"
3637

@@ -425,6 +426,15 @@ void ShenandoahAsserts::assert_marked_strong(void *interior_loc, oop obj, const
425426
}
426427
}
427428

429+
void ShenandoahAsserts::assert_bitmap_clear_above_top(ShenandoahHeapRegion* region) {
430+
ShenandoahMarkingContext* const ctx = ShenandoahHeap::heap()->marking_context();
431+
const HeapWord* top_bitmap = ctx->top_bitmap(region);
432+
// Make sure that top is loaded before any of the marks from the bitmap are loaded. If another
433+
// thread has cleared the bitmap we must not allow any stale reads.
434+
OrderAccess::loadload();
435+
assert(ctx->is_bitmap_range_within_region_clear(top_bitmap, region->end()), "Bitmap above top_bitmap() must be clear");
436+
}
437+
428438
void ShenandoahAsserts::assert_mark_complete(HeapWord* obj, const char* file, int line) {
429439
const ShenandoahHeap* heap = ShenandoahHeap::heap();
430440
const ShenandoahHeapRegion* region = heap->heap_region_containing(obj);

src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include "runtime/mutex.hpp"
3232
#include "utilities/formatBuffer.hpp"
3333

34+
class ShenandoahHeapRegion;
35+
3436
typedef FormatBuffer<8192> ShenandoahMessageBuffer;
3537

3638
class ShenandoahAsserts {
@@ -65,6 +67,7 @@ class ShenandoahAsserts {
6567
static void assert_marked(void* interior_loc, oop obj, const char* file, int line);
6668
static void assert_marked_weak(void* interior_loc, oop obj, const char* file, int line);
6769
static void assert_marked_strong(void* interior_loc, oop obj, const char* file, int line);
70+
static void assert_bitmap_clear_above_top(ShenandoahHeapRegion* region);
6871

6972
// Assert that marking is complete for the generation where this obj resides
7073
static void assert_mark_complete(HeapWord* obj, const char* file, int line);
@@ -137,6 +140,9 @@ class ShenandoahAsserts {
137140
#define shenandoah_assert_marked_strong(interior_loc, obj) \
138141
ShenandoahAsserts::assert_marked_strong(interior_loc, obj, __FILE__, __LINE__)
139142

143+
#define shenandoah_assert_clear_above_top(region) \
144+
ShenandoahAsserts::assert_bitmap_clear_above_top(region)
145+
140146
#define shenandoah_assert_mark_complete(obj) \
141147
ShenandoahAsserts::assert_mark_complete(obj, __FILE__, __LINE__)
142148

@@ -227,6 +233,7 @@ class ShenandoahAsserts {
227233
#define shenandoah_assert_marked_strong_except(interior_loc, obj, exception)
228234
#define shenandoah_assert_marked_strong(interior_loc, obj)
229235

236+
#define shenandoah_assert_clear_above_top(region)
230237
#define shenandoah_assert_mark_complete(obj)
231238

232239
#define shenandoah_assert_in_cset_if(interior_loc, obj, condition)

src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Copyright (c) 2016, 2021, Red Hat, Inc. All rights reserved.
33
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
4-
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
55
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
66
*
77
* This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,6 @@
3535
#include "gc/shenandoah/shenandoahYoungGeneration.hpp"
3636
#include "logging/logStream.hpp"
3737
#include "memory/resourceArea.hpp"
38-
#include "runtime/orderAccess.hpp"
3938

4039
static const char* partition_name(ShenandoahFreeSetPartitionId t) {
4140
switch (t) {
@@ -1510,11 +1509,10 @@ HeapWord* ShenandoahFreeSet::try_allocate_in(ShenandoahHeapRegion* r, Shenandoah
15101509
// coalesce-and-fill processing.
15111510
r->end_preemptible_coalesce_and_fill();
15121511
}
1513-
#ifdef ASSERT
1514-
ShenandoahMarkingContext* const ctx = _heap->marking_context();
1515-
assert(ctx->top_at_mark_start(r) == r->bottom(), "Newly established allocation region starts with TAMS equal to bottom");
1516-
assert(ctx->is_bitmap_range_within_region_clear(ctx->top_bitmap(r), r->end()), "Bitmap above top_bitmap() must be clear");
1517-
#endif
1512+
1513+
assert(_heap->marking_context()->top_at_mark_start(r) == r->bottom(),
1514+
"Newly established allocation region (%zu) must start with TAMS equal to bottom", r->index());
1515+
shenandoah_assert_clear_above_top(r);
15181516
log_debug(gc, free)("Using new region (%zu) for %s (" PTR_FORMAT ").",
15191517
r->index(), req.type_string(), p2i(&req));
15201518
} else {

src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2013, 2020, Red Hat, Inc. All rights reserved.
44
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
55
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -32,22 +32,18 @@
3232
#include "gc/shenandoah/shenandoahGeneration.hpp"
3333
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
3434
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
35-
#include "gc/shenandoah/shenandoahHeapRegionSet.inline.hpp"
3635
#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
3736
#include "gc/shenandoah/shenandoahOldGeneration.hpp"
3837
#include "gc/shenandoah/shenandoahScanRemembered.inline.hpp"
3938
#include "gc/shenandoah/shenandoahYoungGeneration.hpp"
4039
#include "jfr/jfrEvents.hpp"
4140
#include "memory/allocation.hpp"
4241
#include "memory/iterator.inline.hpp"
43-
#include "memory/resourceArea.hpp"
4442
#include "memory/universe.hpp"
4543
#include "oops/oop.inline.hpp"
4644
#include "runtime/globals_extension.hpp"
4745
#include "runtime/java.hpp"
48-
#include "runtime/mutexLocker.hpp"
4946
#include "runtime/os.hpp"
50-
#include "runtime/safepoint.hpp"
5147
#include "utilities/powerOfTwo.hpp"
5248

5349
size_t ShenandoahHeapRegion::RegionCount = 0;
@@ -846,16 +842,7 @@ void ShenandoahHeapRegion::set_affiliation(ShenandoahAffiliation new_affiliation
846842
p2i(top()), p2i(ctx->top_at_mark_start(this)), p2i(_update_watermark.load_relaxed()), p2i(ctx->top_bitmap(this)));
847843
}
848844

849-
#ifdef ASSERT
850-
{
851-
size_t idx = this->index();
852-
HeapWord* top_bitmap = ctx->top_bitmap(this);
853-
854-
assert(ctx->is_bitmap_range_within_region_clear(top_bitmap, _end),
855-
"Region %zu, bitmap should be clear between top_bitmap: " PTR_FORMAT " and end: " PTR_FORMAT, idx,
856-
p2i(top_bitmap), p2i(_end));
857-
}
858-
#endif
845+
shenandoah_assert_clear_above_top(this);
859846

860847
if (region_affiliation == new_affiliation) {
861848
return;

src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ class ShenandoahHeapRegion {
280280
// clears the self_fwd bits. Safety-net reset on region recycle.
281281
ShenandoahSharedFlag _has_self_forwards;
282282

283+
// This is only read/written by a gc worker to avoid unnecessary bitmap resets
283284
bool _needs_bitmap_reset;
284285

285286
public:

src/hotspot/share/gc/shenandoah/shenandoahMarkingContext.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved.
33
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
4-
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
55
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
66
*
77
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
2727
#include "gc/shared/markBitMap.inline.hpp"
2828
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
2929
#include "gc/shenandoah/shenandoahMarkingContext.hpp"
30+
#include "runtime/orderAccess.hpp"
3031

3132
ShenandoahMarkingContext::ShenandoahMarkingContext(MemRegion heap_region, MemRegion bitmap_region, size_t num_regions) :
3233
_mark_bit_map(heap_region, bitmap_region),
@@ -90,6 +91,9 @@ void ShenandoahMarkingContext::clear_bitmap(ShenandoahHeapRegion* r) {
9091

9192
if (top_bitmap > bottom) {
9293
_mark_bit_map.clear_range_large(MemRegion(bottom, top_bitmap));
94+
// All bitmap writes must complete before we update top at bitmap. If these writes were reordered,
95+
// other threads could see stale marks above top, which is not valid.
96+
OrderAccess::storestore();
9397
_top_bitmaps[r->index()] = bottom;
9498
}
9599

0 commit comments

Comments
 (0)