197 bool ShenandoahBarrierSet::arraycopy_loop_3(T* src, T* dst, size_t length, Klass* bound, bool disjoint, |
197 bool ShenandoahBarrierSet::arraycopy_loop_3(T* src, T* dst, size_t length, Klass* bound, bool disjoint, |
198 ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) { |
198 ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) { |
199 switch (storeval_mode) { |
199 switch (storeval_mode) { |
200 case NONE: |
200 case NONE: |
201 return arraycopy_loop<T, CHECKCAST, SATB, NONE>(src, dst, length, bound, disjoint); |
201 return arraycopy_loop<T, CHECKCAST, SATB, NONE>(src, dst, length, bound, disjoint); |
202 case READ_BARRIER: |
202 case RESOLVE_BARRIER: |
203 return arraycopy_loop<T, CHECKCAST, SATB, READ_BARRIER>(src, dst, length, bound, disjoint); |
203 return arraycopy_loop<T, CHECKCAST, SATB, RESOLVE_BARRIER>(src, dst, length, bound, disjoint); |
204 case WRITE_BARRIER: |
204 case EVAC_BARRIER: |
205 return arraycopy_loop<T, CHECKCAST, SATB, WRITE_BARRIER>(src, dst, length, bound, disjoint); |
205 return arraycopy_loop<T, CHECKCAST, SATB, EVAC_BARRIER>(src, dst, length, bound, disjoint); |
206 default: |
206 default: |
207 ShouldNotReachHere(); |
207 ShouldNotReachHere(); |
208 return true; // happy compiler |
208 return true; // happy compiler |
209 } |
209 } |
210 } |
210 } |
266 if (!CompressedOops::is_null(prev)) { |
266 if (!CompressedOops::is_null(prev)) { |
267 oop prev_obj = CompressedOops::decode_not_null(prev); |
267 oop prev_obj = CompressedOops::decode_not_null(prev); |
268 switch (STOREVAL_MODE) { |
268 switch (STOREVAL_MODE) { |
269 case NONE: |
269 case NONE: |
270 break; |
270 break; |
271 case READ_BARRIER: |
271 case RESOLVE_BARRIER: |
272 case WRITE_BARRIER: |
272 case EVAC_BARRIER: |
273 // The write-barrier case cannot really happen. It's traversal-only and traversal |
273 // The evac-barrier case cannot really happen. It's traversal-only and traversal |
274 // doesn't currently use SATB. And even if it did, it would not be fatal to just do the normal RB here. |
274 // doesn't currently use SATB. And even if it did, it would not be fatal to just do the normal resolve here. |
275 prev_obj = ShenandoahBarrierSet::resolve_forwarded_not_null(prev_obj); |
275 prev_obj = ShenandoahBarrierSet::resolve_forwarded_not_null(prev_obj); |
276 } |
276 } |
277 if (!ctx->is_marked(prev_obj)) { |
277 if (!ctx->is_marked(prev_obj)) { |
278 ShenandoahThreadLocalData::satb_mark_queue(thread).enqueue_known_active(prev_obj); |
278 ShenandoahThreadLocalData::satb_mark_queue(thread).enqueue_known_active(prev_obj); |
279 } |
279 } |
291 } |
291 } |
292 |
292 |
293 switch (STOREVAL_MODE) { |
293 switch (STOREVAL_MODE) { |
294 case NONE: |
294 case NONE: |
295 break; |
295 break; |
296 case READ_BARRIER: |
296 case RESOLVE_BARRIER: |
297 obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); |
297 obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); |
298 break; |
298 break; |
299 case WRITE_BARRIER: |
299 case EVAC_BARRIER: |
300 if (_heap->in_collection_set(obj)) { |
300 if (_heap->in_collection_set(obj)) { |
301 oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); |
301 oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj); |
302 if (oopDesc::equals_raw(forw, obj)) { |
302 if (oopDesc::equals_raw(forw, obj)) { |
303 forw = _heap->evacuate_object(forw, thread); |
303 forw = _heap->evacuate_object(forw, thread); |
304 } |
304 } |
335 bool checkcast = HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value; |
335 bool checkcast = HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value; |
336 bool disjoint = HasDecorator<decorators, ARRAYCOPY_DISJOINT>::value; |
336 bool disjoint = HasDecorator<decorators, ARRAYCOPY_DISJOINT>::value; |
337 ArrayCopyStoreValMode storeval_mode; |
337 ArrayCopyStoreValMode storeval_mode; |
338 if (heap->has_forwarded_objects()) { |
338 if (heap->has_forwarded_objects()) { |
339 if (heap->is_concurrent_traversal_in_progress()) { |
339 if (heap->is_concurrent_traversal_in_progress()) { |
340 storeval_mode = WRITE_BARRIER; |
340 storeval_mode = EVAC_BARRIER; |
341 } else if (heap->is_update_refs_in_progress()) { |
341 } else if (heap->is_update_refs_in_progress()) { |
342 storeval_mode = READ_BARRIER; |
342 storeval_mode = RESOLVE_BARRIER; |
343 } else { |
343 } else { |
344 assert(heap->is_idle() || heap->is_evacuation_in_progress(), "must not have anything in progress"); |
344 assert(heap->is_idle() || heap->is_evacuation_in_progress(), "must not have anything in progress"); |
345 storeval_mode = NONE; // E.g. during evac or outside cycle |
345 storeval_mode = NONE; // E.g. during evac or outside cycle |
346 } |
346 } |
347 } else { |
347 } else { |