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