1 /*
  2  * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_GC_SHARED_CARDTABLEBARRIERSET_HPP
 26 #define SHARE_GC_SHARED_CARDTABLEBARRIERSET_HPP
 27 
 28 #include "gc/shared/barrierSet.hpp"
 29 #include "gc/shared/cardTable.hpp"
 30 #include "memory/memRegion.hpp"
 31 #include "utilities/align.hpp"
 32 
 33 // This kind of "BarrierSet" allows a "CollectedHeap" to detect and
 34 // enumerate ref fields that have been modified (since the last
 35 // enumeration.)
 36 
 37 // As it currently stands, this barrier is *imprecise*: when a ref field in
 38 // an object "o" is modified, the card table entry for the card containing
 39 // the head of "o" is dirtied, not necessarily the card containing the
 40 // modified field itself.  For object arrays, however, the barrier *is*
 41 // precise; only the card containing the modified element is dirtied.
 42 // Closures used to scan dirty cards should take these
 43 // considerations into account.
 44 
 45 class CardTableBarrierSet: public BarrierSet {
 46   // Some classes get to look at some private stuff.
 47   friend class VMStructs;
 48 
 49 protected:
 50   typedef CardTable::CardValue CardValue;
 51   CardTable* _card_table;
 52 
 53   CardTableBarrierSet(BarrierSetAssembler* barrier_set_assembler,
 54                       BarrierSetC1* barrier_set_c1,
 55                       BarrierSetC2* barrier_set_c2,
 56                       CardTable* card_table,
 57                       const BarrierSet::FakeRtti& fake_rtti);
 58 
 59 public:
 60   CardTableBarrierSet(CardTable* card_table);
 61   virtual ~CardTableBarrierSet();
 62 
 63   template <DecoratorSet decorators, typename T>
 64   inline void write_ref_field_pre(T* addr) {}
 65 
 66   // Record a reference update. Note that these versions are precise!
 67   // The scanning code has to handle the fact that the write barrier may be
 68   // either precise or imprecise. We make non-virtual inline variants of
 69   // these functions here for performance.
 70   template <DecoratorSet decorators, typename T>
 71   inline void write_ref_field_post(T *addr);
 72 
 73   // Causes all refs in "mr" to be assumed to be modified (by this JavaThread).
 74   virtual void write_region(MemRegion mr);
 75 
 76   // Operations on arrays, or general regions (e.g., for "clone") may be
 77   // optimized by some barriers.
 78 
 79   // Below length is the # array elements being written
 80   virtual void write_ref_array_pre(oop* dst, size_t length,
 81                                    bool dest_uninitialized) {}
 82   virtual void write_ref_array_pre(narrowOop* dst, size_t length,
 83                                    bool dest_uninitialized) {}
 84   // Below count is the # array elements being written, starting
 85   // at the address "start", which may not necessarily be HeapWord-aligned
 86   inline void write_ref_array(HeapWord* start, size_t count);
 87 
 88   CardTable* card_table() const { return _card_table; }
 89 
 90   virtual void on_slowpath_allocation_exit(JavaThread* thread, oop new_obj);
 91 
 92   virtual void print_on(outputStream* st) const;
 93 
 94   template <DecoratorSet decorators, typename BarrierSetT = CardTableBarrierSet>
 95   class AccessBarrier: public BarrierSet::AccessBarrier<decorators, BarrierSetT> {
 96     typedef BarrierSet::AccessBarrier<decorators, BarrierSetT> Raw;
 97 
 98   public:
 99     template <typename T>
100     static void oop_store_in_heap(T* addr, oop value);
101     template <typename T>
102     static oop oop_atomic_cmpxchg_in_heap(T* addr, oop compare_value, oop new_value);
103     template <typename T>
104     static oop oop_atomic_xchg_in_heap(T* addr, oop new_value);
105 
106     template <typename T>
107     static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
108                                       arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
109                                       size_t length);
110 
111     static void clone_in_heap(oop src, oop dst, size_t size);
112 
113     static void oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value) {
114       oop_store_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), value);
115     }
116 
117     static oop oop_atomic_xchg_in_heap_at(oop base, ptrdiff_t offset, oop new_value) {
118       return oop_atomic_xchg_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), new_value);
119     }
120 
121     static oop oop_atomic_cmpxchg_in_heap_at(oop base, ptrdiff_t offset, oop compare_value, oop new_value) {
122       return oop_atomic_cmpxchg_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), compare_value, new_value);
123     }
124   };
125 };
126 
127 template<>
128 struct BarrierSet::GetName<CardTableBarrierSet> {
129   static const BarrierSet::Name value = BarrierSet::CardTableBarrierSet;
130 };
131 
132 template<>
133 struct BarrierSet::GetType<BarrierSet::CardTableBarrierSet> {
134   typedef ::CardTableBarrierSet type;
135 };
136 
137 #endif // SHARE_GC_SHARED_CARDTABLEBARRIERSET_HPP