< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp

Print this page
rev 50076 : Fold Partial GC into Traversal GC


 119 }
 120 
 121 template <typename T, bool CHECKCAST, bool SATB>
 122 bool ShenandoahBarrierSet::arraycopy_loop_3(T* src, T* dst, size_t length, Klass* bound,
 123                                             bool matrix, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) {
 124   if (matrix) {
 125     return arraycopy_loop_4<T, CHECKCAST, SATB, true>(src, dst, length, bound, storeval_mode);
 126   } else {
 127     return arraycopy_loop_4<T, CHECKCAST, SATB, false>(src, dst, length, bound, storeval_mode);
 128   }
 129 }
 130 
 131 template <typename T, bool CHECKCAST, bool SATB, bool MATRIX>
 132 bool ShenandoahBarrierSet::arraycopy_loop_4(T* src, T* dst, size_t length, Klass* bound,
 133                                             ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) {
 134   switch (storeval_mode) {
 135     case NONE:
 136       return arraycopy_loop<T, CHECKCAST, SATB, MATRIX, NONE>(src, dst, length, bound);
 137     case READ_BARRIER:
 138       return arraycopy_loop<T, CHECKCAST, SATB, MATRIX, READ_BARRIER>(src, dst, length, bound);
 139     case WRITE_BARRIER_MAYBE_ENQUEUE:
 140       return arraycopy_loop<T, CHECKCAST, SATB, MATRIX, WRITE_BARRIER_MAYBE_ENQUEUE>(src, dst, length, bound);
 141     case WRITE_BARRIER_ALWAYS_ENQUEUE:
 142       return arraycopy_loop<T, CHECKCAST, SATB, MATRIX, WRITE_BARRIER_ALWAYS_ENQUEUE>(src, dst, length, bound);
 143     default:
 144       ShouldNotReachHere();
 145       return true; // happy compiler
 146   }
 147 }
 148 
 149 template <typename T, bool CHECKCAST, bool SATB, bool MATRIX, ShenandoahBarrierSet::ArrayCopyStoreValMode STOREVAL_MODE>
 150 bool ShenandoahBarrierSet::arraycopy_loop(T* src, T* dst, size_t length, Klass* bound) {
 151   Thread* thread = Thread::current();
 152 
 153   ShenandoahEvacOOMScope oom_evac_scope;
 154 
 155   // We need to handle four cases:
 156   //
 157   // a) src < dst, intersecting, can only copy backward only
 158   //   [...src...]
 159   //         [...dst...]
 160   //
 161   // b) src < dst, non-intersecting, can copy forward/backward
 162   //   [...src...]


 204       enqueue(prev_obj);
 205     }
 206   }
 207 
 208   if (!CompressedOops::is_null(o)) {
 209     oop obj = CompressedOops::decode_not_null(o);
 210 
 211     if (CHECKCAST) {
 212       assert(bound != NULL, "need element klass for checkcast");
 213       if (!oopDesc::is_instanceof_or_null(obj, bound)) {
 214         return false;
 215       }
 216     }
 217 
 218     switch (STOREVAL_MODE) {
 219     case NONE:
 220       break;
 221     case READ_BARRIER:
 222       obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
 223       break;
 224     case WRITE_BARRIER_MAYBE_ENQUEUE:
 225       if (_heap->in_collection_set(obj)) {
 226         oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
 227         if (oopDesc::unsafe_equals(forw, obj)) {
 228           bool evac;
 229           forw = _heap->evacuate_object(forw, thread, evac);
 230           if (evac) {
 231             enqueue(forw);
 232           }
 233         }
 234         obj = forw;
 235       }
 236       break;
 237     case WRITE_BARRIER_ALWAYS_ENQUEUE:
 238       if (_heap->in_collection_set(obj)) {
 239         oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
 240         if (oopDesc::unsafe_equals(forw, obj)) {
 241           bool evac;
 242           forw = _heap->evacuate_object(forw, thread, evac);
 243         }
 244         obj = forw;
 245       }
 246       enqueue(obj);
 247       break;
 248     default:
 249       ShouldNotReachHere();
 250     }
 251 
 252     if (MATRIX) {
 253       _heap->connection_matrix()->set_connected(cur_dst, obj);
 254     }
 255 
 256     RawAccess<OOP_NOT_NULL>::oop_store(cur_dst, obj);
 257   } else {
 258     // Store null.
 259     RawAccess<>::oop_store(cur_dst, o);
 260   }
 261   return true;
 262 }


 273 
 274 template <DecoratorSet decorators, typename BarrierSetT>
 275 template <typename T>
 276 bool ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
 277   assert(((HeapWord*)(void*) src_obj) <= (HeapWord*) src && (HeapWord*) src < (((HeapWord*)(void*) src_obj) + src_obj->size()), "pointer out of object bounds src_obj: %p, src: %p, size: %ul", (void*) src_obj, src, src_obj->size());
 278   assert(((HeapWord*)(void*) dst_obj) <= (HeapWord*) dst && (HeapWord*) dst < (((HeapWord*)(void*) dst_obj) + dst_obj->size()), "pointer out of object bounds dst_obj: "/*POINTER_FORMAT", dst: "POINTER_FORMAT", length: "SIZE_FORMAT, p2i(dst_obj), p2i(dst), length*/);
 279 
 280   ShenandoahHeap* heap = ShenandoahHeap::heap();
 281 
 282   if (!CompressedOops::is_null(src_obj)) {
 283     size_t src_offset = pointer_delta((void*) src, (void*) src_obj, sizeof(T));
 284     src_obj = arrayOop(((ShenandoahBarrierSet*) BarrierSet::barrier_set())->read_barrier(src_obj));
 285     src =  ((T*)(void*) src_obj) + src_offset;
 286   }
 287   if (!CompressedOops::is_null(dst_obj)) {
 288     size_t dst_offset = pointer_delta((void*) dst, (void*) dst_obj, sizeof(T));
 289     dst_obj = arrayOop(((ShenandoahBarrierSet*) BarrierSet::barrier_set())->write_barrier(dst_obj));
 290     dst = ((T*)(void*) dst_obj) + dst_offset;
 291   }
 292 
 293   bool satb = (ShenandoahSATBBarrier || ShenandoahConditionalSATBBarrier) && heap->is_concurrent_mark_in_progress();
 294   bool checkcast = HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value;
 295   ArrayCopyStoreValMode storeval_mode;
 296   if (heap->has_forwarded_objects()) {
 297     if (heap->is_concurrent_partial_in_progress()) {
 298       storeval_mode = WRITE_BARRIER_MAYBE_ENQUEUE;
 299     } else if (heap->is_concurrent_traversal_in_progress()) {
 300       storeval_mode = WRITE_BARRIER_ALWAYS_ENQUEUE;
 301     } else if (heap->is_concurrent_mark_in_progress() || heap->is_update_refs_in_progress()) {
 302       storeval_mode = READ_BARRIER;
 303     } else {
 304       assert(heap->is_idle() || heap->is_evacuation_in_progress(), "must not have anything in progress");
 305       storeval_mode = NONE; // E.g. during evac or outside cycle
 306     }
 307   } else {
 308     assert(heap->is_stable() || heap->is_concurrent_mark_in_progress(), "must not have anything in progress");
 309     storeval_mode = NONE;
 310   }
 311 
 312   if (!satb && !checkcast && !UseShenandoahMatrix && storeval_mode == NONE) {
 313     // Short-circuit to bulk copy.
 314     return Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
 315   }
 316 
 317   Klass* bound = objArrayOop(dst_obj)->element_klass();
 318   ShenandoahBarrierSet* bs = (ShenandoahBarrierSet*) BarrierSet::barrier_set();
 319   return bs->arraycopy_loop_1(src, dst, length, bound, checkcast, satb, UseShenandoahMatrix, storeval_mode);
 320 }


 119 }
 120 
 121 template <typename T, bool CHECKCAST, bool SATB>
 122 bool ShenandoahBarrierSet::arraycopy_loop_3(T* src, T* dst, size_t length, Klass* bound,
 123                                             bool matrix, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) {
 124   if (matrix) {
 125     return arraycopy_loop_4<T, CHECKCAST, SATB, true>(src, dst, length, bound, storeval_mode);
 126   } else {
 127     return arraycopy_loop_4<T, CHECKCAST, SATB, false>(src, dst, length, bound, storeval_mode);
 128   }
 129 }
 130 
 131 template <typename T, bool CHECKCAST, bool SATB, bool MATRIX>
 132 bool ShenandoahBarrierSet::arraycopy_loop_4(T* src, T* dst, size_t length, Klass* bound,
 133                                             ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) {
 134   switch (storeval_mode) {
 135     case NONE:
 136       return arraycopy_loop<T, CHECKCAST, SATB, MATRIX, NONE>(src, dst, length, bound);
 137     case READ_BARRIER:
 138       return arraycopy_loop<T, CHECKCAST, SATB, MATRIX, READ_BARRIER>(src, dst, length, bound);
 139     case WRITE_BARRIER:
 140       return arraycopy_loop<T, CHECKCAST, SATB, MATRIX, WRITE_BARRIER>(src, dst, length, bound);


 141     default:
 142       ShouldNotReachHere();
 143       return true; // happy compiler
 144   }
 145 }
 146 
 147 template <typename T, bool CHECKCAST, bool SATB, bool MATRIX, ShenandoahBarrierSet::ArrayCopyStoreValMode STOREVAL_MODE>
 148 bool ShenandoahBarrierSet::arraycopy_loop(T* src, T* dst, size_t length, Klass* bound) {
 149   Thread* thread = Thread::current();
 150 
 151   ShenandoahEvacOOMScope oom_evac_scope;
 152 
 153   // We need to handle four cases:
 154   //
 155   // a) src < dst, intersecting, can only copy backward only
 156   //   [...src...]
 157   //         [...dst...]
 158   //
 159   // b) src < dst, non-intersecting, can copy forward/backward
 160   //   [...src...]


 202       enqueue(prev_obj);
 203     }
 204   }
 205 
 206   if (!CompressedOops::is_null(o)) {
 207     oop obj = CompressedOops::decode_not_null(o);
 208 
 209     if (CHECKCAST) {
 210       assert(bound != NULL, "need element klass for checkcast");
 211       if (!oopDesc::is_instanceof_or_null(obj, bound)) {
 212         return false;
 213       }
 214     }
 215 
 216     switch (STOREVAL_MODE) {
 217     case NONE:
 218       break;
 219     case READ_BARRIER:
 220       obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
 221       break;
 222     case WRITE_BARRIER:
 223       if (_heap->in_collection_set(obj)) {
 224         oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
 225         if (oopDesc::unsafe_equals(forw, obj)) {
 226           bool evac;
 227           forw = _heap->evacuate_object(forw, thread);













 228         }
 229         obj = forw;
 230       }
 231       enqueue(obj);
 232       break;
 233     default:
 234       ShouldNotReachHere();
 235     }
 236 
 237     if (MATRIX) {
 238       _heap->connection_matrix()->set_connected(cur_dst, obj);
 239     }
 240 
 241     RawAccess<OOP_NOT_NULL>::oop_store(cur_dst, obj);
 242   } else {
 243     // Store null.
 244     RawAccess<>::oop_store(cur_dst, o);
 245   }
 246   return true;
 247 }


 258 
 259 template <DecoratorSet decorators, typename BarrierSetT>
 260 template <typename T>
 261 bool ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
 262   assert(((HeapWord*)(void*) src_obj) <= (HeapWord*) src && (HeapWord*) src < (((HeapWord*)(void*) src_obj) + src_obj->size()), "pointer out of object bounds src_obj: %p, src: %p, size: %ul", (void*) src_obj, src, src_obj->size());
 263   assert(((HeapWord*)(void*) dst_obj) <= (HeapWord*) dst && (HeapWord*) dst < (((HeapWord*)(void*) dst_obj) + dst_obj->size()), "pointer out of object bounds dst_obj: "/*POINTER_FORMAT", dst: "POINTER_FORMAT", length: "SIZE_FORMAT, p2i(dst_obj), p2i(dst), length*/);
 264 
 265   ShenandoahHeap* heap = ShenandoahHeap::heap();
 266 
 267   if (!CompressedOops::is_null(src_obj)) {
 268     size_t src_offset = pointer_delta((void*) src, (void*) src_obj, sizeof(T));
 269     src_obj = arrayOop(((ShenandoahBarrierSet*) BarrierSet::barrier_set())->read_barrier(src_obj));
 270     src =  ((T*)(void*) src_obj) + src_offset;
 271   }
 272   if (!CompressedOops::is_null(dst_obj)) {
 273     size_t dst_offset = pointer_delta((void*) dst, (void*) dst_obj, sizeof(T));
 274     dst_obj = arrayOop(((ShenandoahBarrierSet*) BarrierSet::barrier_set())->write_barrier(dst_obj));
 275     dst = ((T*)(void*) dst_obj) + dst_offset;
 276   }
 277 
 278   bool satb = ShenandoahSATBBarrier && heap->is_concurrent_mark_in_progress();
 279   bool checkcast = HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value;
 280   ArrayCopyStoreValMode storeval_mode;
 281   if (heap->has_forwarded_objects()) {
 282     if (heap->is_concurrent_traversal_in_progress()) {
 283       storeval_mode = WRITE_BARRIER;


 284     } else if (heap->is_concurrent_mark_in_progress() || heap->is_update_refs_in_progress()) {
 285       storeval_mode = READ_BARRIER;
 286     } else {
 287       assert(heap->is_idle() || heap->is_evacuation_in_progress(), "must not have anything in progress");
 288       storeval_mode = NONE; // E.g. during evac or outside cycle
 289     }
 290   } else {
 291     assert(heap->is_stable() || heap->is_concurrent_mark_in_progress(), "must not have anything in progress");
 292     storeval_mode = NONE;
 293   }
 294 
 295   if (!satb && !checkcast && !UseShenandoahMatrix && storeval_mode == NONE) {
 296     // Short-circuit to bulk copy.
 297     return Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
 298   }
 299 
 300   Klass* bound = objArrayOop(dst_obj)->element_klass();
 301   ShenandoahBarrierSet* bs = (ShenandoahBarrierSet*) BarrierSet::barrier_set();
 302   return bs->arraycopy_loop_1(src, dst, length, bound, checkcast, satb, UseShenandoahMatrix, storeval_mode);
 303 }
< prev index next >