Skip to content

[GR-78989] Generational Shenandoah fix: Skip card mark for off-heap stores - #14300

Merged
graalvmbot merged 2 commits into
masterfrom
tkr-shenandoah-GR-78989
Aug 25, 2026
Merged

[GR-78989] Generational Shenandoah fix: Skip card mark for off-heap stores#14300
graalvmbot merged 2 commits into
masterfrom
tkr-shenandoah-GR-78989

Conversation

@graalvmbot

Copy link
Copy Markdown
Collaborator

#14239

Generational Shenandoah crashed with SIGSEGV/SIGBUS in Graal-compiled code when storing an oop into the contents of an OopHandle, such as the store performed by the Thread.setScopedValueCache intrinsic.

This is analogous to the StoreKind.Naitve handling in ZGC.

JohnTortugo and others added 2 commits August 12, 2026 15:52
Generational Shenandoah crashed with SIGSEGV/SIGBUS in Graal compiled
code when storing an oop into the contents of an OopHandle, such as the
store emitted by the Thread.setScopedValueCache intrinsic.

HotSpotShenandoahBarrierSet.writeBarrierType() answers BarrierType.FIELD
for an OopHandleLocationIdentity so that the SATB pre barrier is emitted,
but ShenandoahBarrierSet.addWriteBarriers() then attached a card barrier
unconditionally. An OopHandle's contents live in a native OopStorage
rather than in the Java heap, so the card address computed as
card_table_base + (store_address >> card_shift) lands outside the card
table. The card write then silently corrupts unrelated memory, or faults
when the page it hits happens to be read only.

Gate the card barrier on a new overridable isInHeap() predicate. This
mirrors HotSpot, which gates the card barrier on the IN_HEAP decorator
via ShenandoahBarrierSet::need_card_barrier and splits oop_store_in_heap
from oop_store_not_in_heap. The SATB pre barrier is retained, matching
oop_store_not_in_heap.

Other collectors were unaffected: G1 does not override
writeBarrierType(LocationIdentity) and so emits no barrier here at all,
while ZGC carries the off-heap distinction down to its LIR generators as
StoreKind.Native.

Also pass 32 rather than 8 as the cbz operand size in the AArch64 card
barrier op. cbz has no 8 bit form and asserted on every conditional card
mark. With assertions disabled the encoder falls back to a 32 bit cbz,
which is accidentally correct because the preceding ldrb zero extends, so
this is benign in a product build but makes the path impossible to
exercise in an assertion enabled build. It is a prerequisite for the
in-heap case of the test added here.

Add ShenandoahOopHandleBarrierTest, asserting that an OopHandle oop store
keeps its SATB pre barrier and is not card marked, and that an ordinary
in-heap oop store still is. Two notes for anyone extending it: Shenandoah
inserts barriers in the low tier, so the verification phase hooks
LOW_TIER_BARRIER_ADDITION rather than the mid tier used by the card table
collectors, and barriers are matched by address rather than by graph
adjacency because PublishWrites can sit between a write and its barriers.

Verified on aarch64 with a ScopedValue stress reproducer that drives
first-time ScopedValue.get() calls on freshly created threads. Unpatched
it crashes within a second; patched it survives 271M virtual thread and
1.8M platform thread iterations, including under -XX:+ShenandoahVerify,
which also validates remembered set integrity. The new test fails without
the isInHeap() gate and passes with it. jdk.graal.compiler.hotspot.test
passes 23603 tests under -XX:ShenandoahGCMode=generational, where the cbz
assertion previously prevented compiling any in-heap oop store.
@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Aug 25, 2026
@graalvmbot graalvmbot changed the title [GR-78989] Generatioanl Shenandoah fix: Skip card mark for off-heap stores [GR-78989] Generational Shenandoah fix: Skip card mark for off-heap stores Aug 25, 2026
@graalvmbot
graalvmbot merged commit 6c36a76 into master Aug 25, 2026
3 checks passed
@graalvmbot
graalvmbot deleted the tkr-shenandoah-GR-78989 branch August 25, 2026 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Verified All contributors have signed the Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants