Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8265677

CMS: CardTableBarrierSet::write_ref_array_work() lacks storestore barrier

XMLWordPrintable

    • gc
    • b01

      CMS precleaning is a phase where the card table is scanned for dirty cards. A
      dirty card is an indication for GC that references in corresponding objects were
      updated. In the precleaning phase the references of these objects are followed
      and the objects reached are marked.

      Precleaning is a concurrent phase therefore accesses to the card table need to
      be ordered with corresponding accesses to references.

      On mutator side storing references must preceed the stores for marking the
      corresponding cards dirty.

      This ordering is missing when copying object arrays in the interpreter or when
      default versions of array copy routines like `StubRoutines::oop_copy()` are used.

      This is the stack where cards are marked dirty after an arraycopy in the
      interpreter. Copying array elements happens in `oop_arraycopy_in_heap()`[1]. The
      card table is dirtied in `write_ref_array_work()`[2]. Between a storestore barrier
      is missing.

      ```
       CardTableBarrierSet::write_ref_array_work()
       ModRefBarrierSet::write_ref_array()
       ModRefBarrierSet::AccessBarrier<36225142ul, CardTableBarrierSet>::oop_arraycopy_in_heap<unsigned int>()
       AccessInternal::PostRuntimeDispatch<CardTableBarrierSet::AccessBarrier<36225142ul, CardTableBarrierSet>,()
       AccessInternal::RuntimeDispatch<36225110ul, HeapWord,()
       AccessInternal::RuntimeDispatch<36225110ul, HeapWord,()
       AccessInternal::PreRuntimeDispatch::arraycopy<36225110ul, HeapWord>()
       AccessInternal::arraycopy_reduce_types<36225108ul>()
       AccessInternal::arraycopy<36175876ul, HeapWord>()
       Access<36175872ul>::oop_arraycopy<HeapWord>()
       ArrayAccess<33554432ul>::oop_arraycopy()
       ObjArrayKlass::do_copy()
       ObjArrayKlass::copy_array()
       JVM_ArrayCopy()
      ```

      Note that in `CardTableBarrierSet::write_ref_field_post(T* field, oop newVal)` [3]
      for example the card table store is given release semantics.

      `CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier()` on AARCH64[4]
      and PPC64[5] issue a StoreStore barrier.

      [1] Copying array elements in `oop_arraycopy_in_heap()`
          https://github.com/openjdk/jdk11u/blob/73eef16128417f4a489c4dde47383bb4a00f39d4/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp#L106
          
      [2] Marking cards dirty for the updates of [1] in `write_ref_array_work()`
          https://github.com/openjdk/jdk11u/blob/master/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp#L82

      [3] Card table store with release sematics in CardTableBarrierSet::write_ref_field_post(T* field, oop newVal)
          https://github.com/openjdk/jdk11u/blob/73eef16128417f4a489c4dde47383bb4a00f39d4/src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp#L36-L37

      [4] StoreStore barrier in AARCH64 version of `CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier()`
          https://github.com/openjdk/jdk11u/blob/73eef16128417f4a489c4dde47383bb4a00f39d4/src/hotspot/cpu/aarch64/gc/shared/cardTableBarrierSetAssembler_aarch64.cpp#L86

      [5] StoreStore barrier in PPC64 version of `CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier()`
          https://github.com/openjdk/jdk11u/blob/73eef16128417f4a489c4dde47383bb4a00f39d4/src/hotspot/cpu/ppc/gc/shared/cardTableBarrierSetAssembler_ppc.cpp#L53

            rrich Richard Reingruber
            rrich Richard Reingruber
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: