70
71 void write_ref_array_pre(narrowOop* dst, size_t count, bool dest_uninitialized);
72
73 // We export this to make it available in cases where the static
74 // type of the barrier set is known. Note that it is non-virtual.
75 template <class T> inline void inline_write_ref_field_pre(T* field, oop new_val);
76
77 // These are the more general virtual versions.
78 void write_ref_field_pre_work(oop* field, oop new_val);
79 void write_ref_field_pre_work(narrowOop* field, oop new_val);
80 void write_ref_field_pre_work(void* field, oop new_val);
81
82 void write_ref_field_work(void* v, oop o, bool release = false);
83 void write_region(MemRegion mr);
84
85 virtual void on_thread_create(Thread* thread);
86 virtual void on_thread_destroy(Thread* thread);
87 virtual void on_thread_attach(Thread* thread);
88 virtual void on_thread_detach(Thread* thread);
89
90 virtual oop read_barrier(oop src);
91
92 static inline oop resolve_forwarded_not_null(oop p);
93 static inline oop resolve_forwarded(oop p);
94
95 virtual oop write_barrier(oop obj);
96
97 oop write_barrier_mutator(oop obj);
98
99 virtual oop storeval_barrier(oop obj);
100
101 virtual void keep_alive_barrier(oop obj);
102
103 bool obj_equals(oop obj1, oop obj2);
104
105 #ifdef CHECK_UNHANDLED_OOPS
106 bool oop_equals_operator_allowed() { return !ShenandoahVerifyObjectEquals; }
107 #endif
108
109 void enqueue(oop obj);
110
111 private:
112 inline bool need_update_refs_barrier();
113
114 template <class T, bool STOREVAL_WRITE_BARRIER>
115 void write_ref_array_loop(HeapWord* start, size_t count);
116
117 oop write_barrier_impl(oop obj);
118
119 static void keep_alive_if_weak(DecoratorSet decorators, oop value) {
120 assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known");
121 const bool on_strong_oop_ref = (decorators & ON_STRONG_OOP_REF) != 0;
122 const bool peek = (decorators & AS_NO_KEEPALIVE) != 0;
123 if (!peek && !on_strong_oop_ref && value != NULL) {
124 ShenandoahBarrierSet::barrier_set()->keep_alive_barrier(value);
125 }
126 }
127
128 template <typename T>
129 bool arraycopy_loop_1(T* src, T* dst, size_t length, Klass* bound,
130 bool checkcast, bool satb, bool disjoint, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
131
132 template <typename T, bool CHECKCAST>
133 bool arraycopy_loop_2(T* src, T* dst, size_t length, Klass* bound,
134 bool satb, bool disjoint, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
135
136 template <typename T, bool CHECKCAST, bool SATB>
137 bool arraycopy_loop_3(T* src, T* dst, size_t length, Klass* bound,
138 bool disjoint, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
139
140 template <typename T, bool CHECKCAST, bool SATB, ShenandoahBarrierSet::ArrayCopyStoreValMode STOREVAL_MODE>
141 bool arraycopy_loop(T* src, T* dst, size_t length, Klass* bound, bool disjoint);
142
143 template <typename T, bool CHECKCAST, bool SATB, ShenandoahBarrierSet::ArrayCopyStoreValMode STOREVAL_MODE>
144 bool arraycopy_element(T* cur_src, T* cur_dst, Klass* bound, Thread* const thread, ShenandoahMarkingContext* const ctx);
145
146 public:
147 // Callbacks for runtime accesses.
148 template <DecoratorSet decorators, typename BarrierSetT = ShenandoahBarrierSet>
149 class AccessBarrier: public BarrierSet::AccessBarrier<decorators, BarrierSetT> {
150 typedef BarrierSet::AccessBarrier<decorators, BarrierSetT> Raw;
151
152 public:
153 // Primitive heap accesses. These accessors get resolved when
154 // IN_HEAP is set (e.g. when using the HeapAccess API), it is
155 // not an oop_* overload, and the barrier strength is AS_NORMAL.
156 template <typename T>
157 static T load_in_heap(T* addr) {
158 ShouldNotReachHere();
159 return Raw::template load<T>(addr);
160 }
161
162 template <typename T>
163 static T load_in_heap_at(oop base, ptrdiff_t offset) {
164 base = ShenandoahBarrierSet::resolve_forwarded(base);
165 return Raw::template load_at<T>(base, offset);
166 }
167
168 template <typename T>
169 static void store_in_heap(T* addr, T value) {
170 ShouldNotReachHere();
171 Raw::store(addr, value);
172 }
173
174 template <typename T>
175 static void store_in_heap_at(oop base, ptrdiff_t offset, T value) {
176 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base);
177 Raw::store_at(base, offset, value);
178 }
179
180 template <typename T>
181 static T atomic_cmpxchg_in_heap(T new_value, T* addr, T compare_value) {
182 ShouldNotReachHere();
183 return Raw::atomic_cmpxchg(new_value, addr, compare_value);
184 }
185
186 template <typename T>
187 static T atomic_cmpxchg_in_heap_at(T new_value, oop base, ptrdiff_t offset, T compare_value) {
188 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base);
189 return Raw::atomic_cmpxchg_at(new_value, base, offset, compare_value);
190 }
191
192 template <typename T>
193 static T atomic_xchg_in_heap(T new_value, T* addr) {
194 ShouldNotReachHere();
195 return Raw::atomic_xchg(new_value, addr);
196 }
197
198 template <typename T>
199 static T atomic_xchg_in_heap_at(T new_value, oop base, ptrdiff_t offset) {
200 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base);
201 return Raw::atomic_xchg_at(new_value, base, offset);
202 }
203
204 template <typename T>
205 static void arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
206 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
207 size_t length);
208
209 // Heap oop accesses. These accessors get resolved when
210 // IN_HEAP is set (e.g. when using the HeapAccess API), it is
211 // an oop_* overload, and the barrier strength is AS_NORMAL.
212 template <typename T>
213 static oop oop_load_in_heap(T* addr) {
214 // ShouldNotReachHere();
215 oop value = Raw::template oop_load<oop>(addr);
216 keep_alive_if_weak(decorators, value);
217 return value;
218 }
219
220 static oop oop_load_in_heap_at(oop base, ptrdiff_t offset) {
221 base = ShenandoahBarrierSet::resolve_forwarded(base);
222 oop value = Raw::template oop_load_at<oop>(base, offset);
223 keep_alive_if_weak(AccessBarrierSupport::resolve_possibly_unknown_oop_ref_strength<decorators>(base, offset), value);
224 return value;
225 }
226
227 template <typename T>
228 static void oop_store_in_heap(T* addr, oop value) {
229 const bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0;
230 if (keep_alive) {
231 ShenandoahBarrierSet::barrier_set()->write_ref_field_pre_work(addr, value);
232 }
233 Raw::oop_store(addr, value);
234 }
235
236 static void oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value) {
237 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base);
238 value = ShenandoahBarrierSet::barrier_set()->storeval_barrier(value);
239
240 oop_store_in_heap(AccessInternal::oop_field_addr<decorators>(base, offset), value);
241 }
242
243 template <typename T>
244 static oop oop_atomic_cmpxchg_in_heap(oop new_value, T* addr, oop compare_value);
245
246 static oop oop_atomic_cmpxchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value) {
247 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base);
248 new_value = ShenandoahBarrierSet::barrier_set()->storeval_barrier(new_value);
249 return oop_atomic_cmpxchg_in_heap(new_value, AccessInternal::oop_field_addr<decorators>(base, offset), compare_value);
250 }
251
252 template <typename T>
253 static oop oop_atomic_xchg_in_heap(oop new_value, T* addr);
254
255 static oop oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset) {
256 base = ShenandoahBarrierSet::barrier_set()->write_barrier(base);
257 new_value = ShenandoahBarrierSet::barrier_set()->storeval_barrier(new_value);
258 return oop_atomic_xchg_in_heap(new_value, AccessInternal::oop_field_addr<decorators>(base, offset));
259 }
260
261 template <typename T>
262 static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
263 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
264 size_t length);
265
266 // Clone barrier support
267 static void clone_in_heap(oop src, oop dst, size_t size);
268
269 // Needed for loads on non-heap weak references
270 template <typename T>
271 static oop oop_load_not_in_heap(T* addr) {
272 oop value = Raw::oop_load_not_in_heap(addr);
273 keep_alive_if_weak(decorators, value);
274 return value;
275 }
276
277 static oop resolve(oop obj) {
278 return ShenandoahBarrierSet::barrier_set()->write_barrier(obj);
279 }
280
281 static bool equals(oop o1, oop o2) {
282 return ShenandoahBarrierSet::barrier_set()->obj_equals(o1, o2);
283 }
284
285 };
286
287 };
288
289 template<>
290 struct BarrierSet::GetName<ShenandoahBarrierSet> {
291 static const BarrierSet::Name value = BarrierSet::ShenandoahBarrierSet;
292 };
293
294 template<>
295 struct BarrierSet::GetType<BarrierSet::ShenandoahBarrierSet> {
296 typedef ::ShenandoahBarrierSet type;
297 };
298
299 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSET_HPP
|
70
71 void write_ref_array_pre(narrowOop* dst, size_t count, bool dest_uninitialized);
72
73 // We export this to make it available in cases where the static
74 // type of the barrier set is known. Note that it is non-virtual.
75 template <class T> inline void inline_write_ref_field_pre(T* field, oop new_val);
76
77 // These are the more general virtual versions.
78 void write_ref_field_pre_work(oop* field, oop new_val);
79 void write_ref_field_pre_work(narrowOop* field, oop new_val);
80 void write_ref_field_pre_work(void* field, oop new_val);
81
82 void write_ref_field_work(void* v, oop o, bool release = false);
83 void write_region(MemRegion mr);
84
85 virtual void on_thread_create(Thread* thread);
86 virtual void on_thread_destroy(Thread* thread);
87 virtual void on_thread_attach(Thread* thread);
88 virtual void on_thread_detach(Thread* thread);
89
90 static inline oop resolve_forwarded_not_null(oop p);
91 static inline oop resolve_forwarded(oop p);
92
93 void storeval_barrier(oop obj);
94 void keep_alive_barrier(oop obj);
95
96 oop load_reference_barrier(oop obj);
97 oop load_reference_barrier_mutator(oop obj);
98 oop load_reference_barrier_not_null(oop obj);
99
100 void enqueue(oop obj);
101
102 private:
103 inline bool need_update_refs_barrier();
104
105 template <class T, bool STOREVAL_WRITE_BARRIER>
106 void write_ref_array_loop(HeapWord* start, size_t count);
107
108 oop load_reference_barrier_impl(oop obj);
109
110 static void keep_alive_if_weak(DecoratorSet decorators, oop value) {
111 assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Reference strength must be known");
112 const bool on_strong_oop_ref = (decorators & ON_STRONG_OOP_REF) != 0;
113 const bool peek = (decorators & AS_NO_KEEPALIVE) != 0;
114 if (!peek && !on_strong_oop_ref && value != NULL) {
115 ShenandoahBarrierSet::barrier_set()->keep_alive_barrier(value);
116 }
117 }
118
119 template <typename T>
120 bool arraycopy_loop_1(T* src, T* dst, size_t length, Klass* bound,
121 bool checkcast, bool satb, bool disjoint, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
122
123 template <typename T, bool CHECKCAST>
124 bool arraycopy_loop_2(T* src, T* dst, size_t length, Klass* bound,
125 bool satb, bool disjoint, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
126
127 template <typename T, bool CHECKCAST, bool SATB>
128 bool arraycopy_loop_3(T* src, T* dst, size_t length, Klass* bound,
129 bool disjoint, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
130
131 template <typename T, bool CHECKCAST, bool SATB, ShenandoahBarrierSet::ArrayCopyStoreValMode STOREVAL_MODE>
132 bool arraycopy_loop(T* src, T* dst, size_t length, Klass* bound, bool disjoint);
133
134 template <typename T, bool CHECKCAST, bool SATB, ShenandoahBarrierSet::ArrayCopyStoreValMode STOREVAL_MODE>
135 bool arraycopy_element(T* cur_src, T* cur_dst, Klass* bound, Thread* const thread, ShenandoahMarkingContext* const ctx);
136
137 public:
138 // Callbacks for runtime accesses.
139 template <DecoratorSet decorators, typename BarrierSetT = ShenandoahBarrierSet>
140 class AccessBarrier: public BarrierSet::AccessBarrier<decorators, BarrierSetT> {
141 typedef BarrierSet::AccessBarrier<decorators, BarrierSetT> Raw;
142
143 template <typename T>
144 static oop oop_atomic_cmpxchg_in_heap_impl(oop new_value, T* addr, oop compare_value);
145
146 template <typename T>
147 static oop oop_atomic_xchg_in_heap_impl(oop new_value, T* addr);
148
149 public:
150 // Heap oop accesses. These accessors get resolved when
151 // IN_HEAP is set (e.g. when using the HeapAccess API), it is
152 // an oop_* overload, and the barrier strength is AS_NORMAL.
153 template <typename T>
154 static oop oop_load_in_heap(T* addr);
155 static oop oop_load_in_heap_at(oop base, ptrdiff_t offset);
156
157 template <typename T>
158 static void oop_store_in_heap(T* addr, oop value);
159 static void oop_store_in_heap_at(oop base, ptrdiff_t offset, oop value);
160
161 template <typename T>
162 static oop oop_atomic_cmpxchg_in_heap(oop new_value, T* addr, oop compare_value);
163 static oop oop_atomic_cmpxchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value);
164
165 template <typename T>
166 static oop oop_atomic_xchg_in_heap(oop new_value, T* addr);
167 static oop oop_atomic_xchg_in_heap_at(oop new_value, oop base, ptrdiff_t offset);
168
169 template <typename T>
170 static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
171 arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
172 size_t length);
173
174 // Clone barrier support
175 static void clone_in_heap(oop src, oop dst, size_t size);
176
177 // Needed for loads on non-heap weak references
178 template <typename T>
179 static oop oop_load_not_in_heap(T* addr);
180
181 template <typename T>
182 static oop oop_atomic_cmpxchg_not_in_heap(oop new_value, T* addr, oop compare_value);
183
184 template <typename T>
185 static oop oop_atomic_xchg_not_in_heap(oop new_value, T* addr);
186
187 };
188
189 };
190
191 template<>
192 struct BarrierSet::GetName<ShenandoahBarrierSet> {
193 static const BarrierSet::Name value = BarrierSet::ShenandoahBarrierSet;
194 };
195
196 template<>
197 struct BarrierSet::GetType<BarrierSet::ShenandoahBarrierSet> {
198 typedef ::ShenandoahBarrierSet type;
199 };
200
201 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSET_HPP
|