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 }
|