< prev index next >

src/share/vm/gc/shenandoah/shenandoahPartialGC.cpp

Print this page
rev 13080 : Partial GC: Only evacuating threads push oop to work queue.


 262   }
 263 
 264   policy->record_phase_end(ShenandoahCollectorPolicy::partial_gc);
 265   _heap->gc_timer()->register_gc_end();
 266 }
 267 
 268 void ShenandoahPartialGC::reset() {
 269   _heap->collection_set()->clear();
 270   _heap->clear_cset_fast_test();
 271   _root_regions->clear();
 272 }
 273 
 274 template <class T>
 275 void ShenandoahPartialGC::process_oop(T* p, Thread* thread, SCMObjToScanQueue* queue, bool update_matrix) {
 276   T o = oopDesc::load_heap_oop(p);
 277   if (! oopDesc::is_null(o)) {
 278     oop obj = oopDesc::decode_heap_oop_not_null(o);
 279     if (_heap->in_collection_set(obj)) {
 280       oop forw = ShenandoahBarrierSet::resolve_oop_static_not_null(obj);
 281       if (oopDesc::unsafe_equals(obj, forw)) {
 282         forw = _heap->evacuate_object(obj, thread);
 283       }
 284       assert(! oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must be evacuated");
 285       // TODO: Only the thread that succeeds *evacuating* the object should need to
 286       // update the matrix and push the evacuated object to its queue. This would also
 287       // enable to only have one CAS (the one in evacuate_object()) and use simple
 288       // store for updating the ref.
 289       oop oldval = _heap->atomic_compare_exchange_oop(forw, p, obj);
 290       if (oopDesc::unsafe_equals(obj, oldval)) {
 291         assert(forw->is_oop(), "sanity");
 292         bool succeeded = queue->push(SCMTask(forw));
 293         assert(succeeded, "must succeed to push to task queue");
 294       } else {
 295         assert(oopDesc::unsafe_equals(oldval, forw), "other thread must have punched the same forwarded oop");
 296       }




 297       obj = forw; // For matrix update below.
 298     }
 299     // TODO: Make this templated
 300     if (update_matrix) {
 301 #ifdef ASSERT
 302       oop forw = ShenandoahBarrierSet::resolve_oop_static_not_null(obj);
 303       assert(oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must not be evacuated");
 304 #endif
 305       uint from_idx = _heap->heap_region_index_containing(p);
 306       uint to_idx = _heap->heap_region_index_containing(obj);
 307       _heap->connection_matrix()->set_connected(from_idx, to_idx, true);
 308     }
 309   }
 310 }
 311 
 312 bool ShenandoahPartialGC::is_in_root_region(oop obj) {
 313   // TODO: make this very fast!!
 314   ShenandoahHeapRegion* r = _heap->heap_region_containing(obj);
 315   return _root_regions->contains(r);
 316 }


 262   }
 263 
 264   policy->record_phase_end(ShenandoahCollectorPolicy::partial_gc);
 265   _heap->gc_timer()->register_gc_end();
 266 }
 267 
 268 void ShenandoahPartialGC::reset() {
 269   _heap->collection_set()->clear();
 270   _heap->clear_cset_fast_test();
 271   _root_regions->clear();
 272 }
 273 
 274 template <class T>
 275 void ShenandoahPartialGC::process_oop(T* p, Thread* thread, SCMObjToScanQueue* queue, bool update_matrix) {
 276   T o = oopDesc::load_heap_oop(p);
 277   if (! oopDesc::is_null(o)) {
 278     oop obj = oopDesc::decode_heap_oop_not_null(o);
 279     if (_heap->in_collection_set(obj)) {
 280       oop forw = ShenandoahBarrierSet::resolve_oop_static_not_null(obj);
 281       if (oopDesc::unsafe_equals(obj, forw)) {
 282         bool evacuated = false;
 283         forw = _heap->evacuate_object(obj, thread, evacuated);
 284 
 285         // Only the thread that succeeded evacuating this object pushes it to its work queue.
 286         if (evacuated) {




 287           assert(forw->is_oop(), "sanity");
 288           bool succeeded = queue->push(SCMTask(forw));
 289           assert(succeeded, "must succeed to push to task queue");


 290         }
 291       }
 292       assert(! oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must be evacuated");
 293       // Update reference.
 294       oopDesc::encode_store_heap_oop_not_null(p, forw);
 295       obj = forw; // For matrix update below.
 296     }
 297     // TODO: Make this templated
 298     if (update_matrix) {
 299 #ifdef ASSERT
 300       oop forw = ShenandoahBarrierSet::resolve_oop_static_not_null(obj);
 301       assert(oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must not be evacuated");
 302 #endif
 303       uint from_idx = _heap->heap_region_index_containing(p);
 304       uint to_idx = _heap->heap_region_index_containing(obj);
 305       _heap->connection_matrix()->set_connected(from_idx, to_idx, true);
 306     }
 307   }
 308 }
 309 
 310 bool ShenandoahPartialGC::is_in_root_region(oop obj) {
 311   // TODO: make this very fast!!
 312   ShenandoahHeapRegion* r = _heap->heap_region_containing(obj);
 313   return _root_regions->contains(r);
 314 }
< prev index next >