diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp index aee33efeb57..caab8842ec9 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp @@ -125,7 +125,7 @@ class ShenandoahBarrierSet: public BarrierSet { inline oop oop_xchg(DecoratorSet decorators, T* addr, oop new_value); template - void write_ref_field_post(T* field); + void write_ref_field_post(T* field, oop new_value); void write_ref_array(HeapWord* start, size_t count); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp index 86244711844..5b61a98eb62 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp @@ -189,23 +189,28 @@ inline void ShenandoahBarrierSet::keep_alive_if_weak(DecoratorSet decorators, oo } template -inline void ShenandoahBarrierSet::write_ref_field_post(T* field) { +inline void ShenandoahBarrierSet::write_ref_field_post(T* field, oop new_value) { assert(ShenandoahCardBarrier, "Should have been checked by caller"); - if (_heap->is_in_young(field)) { - // Young field stores do not require card mark. + + if (new_value == nullptr) { + // Null reference stores do not require card mark. return; } - T heap_oop = RawAccess<>::oop_load(field); - if (CompressedOops::is_null(heap_oop)) { - // Null reference store do not require card mark. + + if (_heap->is_in_young(field)) { + // Young field stores do not require card mark. return; } - oop obj = CompressedOops::decode_not_null(heap_oop); - if (!_heap->is_in_young(obj)) { + + if (!_heap->is_in_young(new_value)) { // Not an old->young reference store. return; } + volatile CardTable::CardValue* byte = card_table()->byte_for(field); + if (UseCondCardMark && (*byte == CardTable::dirty_card_val())) { + return; + } *byte = CardTable::dirty_card_val(); } @@ -296,7 +301,7 @@ inline void ShenandoahBarrierSet::AccessBarrier::oop_st oop_store_common(addr, value); if (ShenandoahCardBarrier) { ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set(); - bs->write_ref_field_post(addr); + bs->write_ref_field_post(addr, value); } } @@ -320,7 +325,7 @@ inline oop ShenandoahBarrierSet::AccessBarrier::oop_ato ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set(); oop result = bs->oop_cmpxchg(decorators, addr, compare_value, new_value); if (ShenandoahCardBarrier) { - bs->write_ref_field_post(addr); + bs->write_ref_field_post(addr, new_value); } return result; } @@ -333,7 +338,7 @@ inline oop ShenandoahBarrierSet::AccessBarrier::oop_ato auto addr = AccessInternal::oop_field_addr(base, offset); oop result = bs->oop_cmpxchg(resolved_decorators, addr, compare_value, new_value); if (ShenandoahCardBarrier) { - bs->write_ref_field_post(addr); + bs->write_ref_field_post(addr, new_value); } return result; } @@ -353,7 +358,7 @@ inline oop ShenandoahBarrierSet::AccessBarrier::oop_ato ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set(); oop result = bs->oop_xchg(decorators, addr, new_value); if (ShenandoahCardBarrier) { - bs->write_ref_field_post(addr); + bs->write_ref_field_post(addr, new_value); } return result; } @@ -366,7 +371,7 @@ inline oop ShenandoahBarrierSet::AccessBarrier::oop_ato auto addr = AccessInternal::oop_field_addr(base, offset); oop result = bs->oop_xchg(resolved_decorators, addr, new_value); if (ShenandoahCardBarrier) { - bs->write_ref_field_post(addr); + bs->write_ref_field_post(addr, new_value); } return result; }