diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp index b176446452a19..951b08007ac60 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp @@ -191,8 +191,27 @@ inline void ShenandoahBarrierSet::keep_alive_if_weak(DecoratorSet decorators, oo template inline void ShenandoahBarrierSet::write_ref_field_post(T* field) { assert(ShenandoahCardBarrier, "Should have been checked by caller"); + if (_heap->is_in_young(field)) { + // Young field stores do not require card mark. + return; + } + T heap_oop = RawAccess<>::oop_load(field); + if (CompressedOops::is_null(heap_oop)) { + return; + } + oop obj = CompressedOops::decode_not_null(heap_oop); + if (!_heap->is_in_young(obj)) { + // Young object -> old field stores do not require card mark. + return; + } volatile CardTable::CardValue* byte = card_table()->byte_for(field); - *byte = CardTable::dirty_card_val(); + if (UseCondCardMark) { + if (*byte != CardTable::dirty_card_val()) { + *byte = CardTable::dirty_card_val(); + } + } else { + *byte = CardTable::dirty_card_val(); + } } template