223 }
224
225 template<UpdateRefsMode UPDATE_REFS, StringDedupMode STRING_DEDUP>
226 void do_buffer_impl(void **buffer, size_t size) {
227 for (size_t i = 0; i < size; ++i) {
228 oop *p = (oop *) &buffer[i];
229 ShenandoahConcurrentMark::mark_through_ref<oop, UPDATE_REFS, STRING_DEDUP>(p, _heap, _queue, _mark_context);
230 }
231 }
232 };
233
234 template<class T, UpdateRefsMode UPDATE_REFS, StringDedupMode STRING_DEDUP>
235 inline void ShenandoahConcurrentMark::mark_through_ref(T *p, ShenandoahHeap* heap, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context) {
236 T o = RawAccess<>::oop_load(p);
237 if (!CompressedOops::is_null(o)) {
238 oop obj = CompressedOops::decode_not_null(o);
239 switch (UPDATE_REFS) {
240 case NONE:
241 break;
242 case RESOLVE:
243 obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
244 break;
245 case SIMPLE:
246 // We piggy-back reference updating to the marking tasks.
247 obj = heap->update_with_forwarded_not_null(p, obj);
248 break;
249 case CONCURRENT:
250 obj = heap->maybe_update_with_forwarded_not_null(p, obj);
251 break;
252 default:
253 ShouldNotReachHere();
254 }
255
256 // Note: Only when concurrently updating references can obj be different
257 // (that is, really different, not just different from-/to-space copies of the same)
258 // from the one we originally loaded. Mutator thread can beat us by writing something
259 // else into the location. In that case, we would mark through that updated value,
260 // on the off-chance it is not handled by other means (e.g. via SATB). However,
261 // if that write was NULL, we don't need to do anything else.
262 if (UPDATE_REFS != CONCURRENT || !CompressedOops::is_null(obj)) {
263 shenandoah_assert_not_forwarded(p, obj);
|
223 }
224
225 template<UpdateRefsMode UPDATE_REFS, StringDedupMode STRING_DEDUP>
226 void do_buffer_impl(void **buffer, size_t size) {
227 for (size_t i = 0; i < size; ++i) {
228 oop *p = (oop *) &buffer[i];
229 ShenandoahConcurrentMark::mark_through_ref<oop, UPDATE_REFS, STRING_DEDUP>(p, _heap, _queue, _mark_context);
230 }
231 }
232 };
233
234 template<class T, UpdateRefsMode UPDATE_REFS, StringDedupMode STRING_DEDUP>
235 inline void ShenandoahConcurrentMark::mark_through_ref(T *p, ShenandoahHeap* heap, ShenandoahObjToScanQueue* q, ShenandoahMarkingContext* const mark_context) {
236 T o = RawAccess<>::oop_load(p);
237 if (!CompressedOops::is_null(o)) {
238 oop obj = CompressedOops::decode_not_null(o);
239 switch (UPDATE_REFS) {
240 case NONE:
241 break;
242 case RESOLVE:
243 if (heap->in_collection_set(obj)) {
244 obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
245 }
246 break;
247 case SIMPLE:
248 // We piggy-back reference updating to the marking tasks.
249 obj = heap->update_with_forwarded_not_null(p, obj);
250 break;
251 case CONCURRENT:
252 obj = heap->maybe_update_with_forwarded_not_null(p, obj);
253 break;
254 default:
255 ShouldNotReachHere();
256 }
257
258 // Note: Only when concurrently updating references can obj be different
259 // (that is, really different, not just different from-/to-space copies of the same)
260 // from the one we originally loaded. Mutator thread can beat us by writing something
261 // else into the location. In that case, we would mark through that updated value,
262 // on the off-chance it is not handled by other means (e.g. via SATB). However,
263 // if that write was NULL, we don't need to do anything else.
264 if (UPDATE_REFS != CONCURRENT || !CompressedOops::is_null(obj)) {
265 shenandoah_assert_not_forwarded(p, obj);
|