< 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.
@@ -277,25 +277,23 @@
if (! oopDesc::is_null(o)) {
oop obj = oopDesc::decode_heap_oop_not_null(o);
if (_heap->in_collection_set(obj)) {
oop forw = ShenandoahBarrierSet::resolve_oop_static_not_null(obj);
if (oopDesc::unsafe_equals(obj, forw)) {
- forw = _heap->evacuate_object(obj, thread);
- }
- assert(! oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must be evacuated");
- // TODO: Only the thread that succeeds *evacuating* the object should need to
- // update the matrix and push the evacuated object to its queue. This would also
- // enable to only have one CAS (the one in evacuate_object()) and use simple
- // store for updating the ref.
- oop oldval = _heap->atomic_compare_exchange_oop(forw, p, obj);
- if (oopDesc::unsafe_equals(obj, oldval)) {
+ bool evacuated = false;
+ forw = _heap->evacuate_object(obj, thread, evacuated);
+
+ // Only the thread that succeeded evacuating this object pushes it to its work queue.
+ if (evacuated) {
assert(forw->is_oop(), "sanity");
bool succeeded = queue->push(SCMTask(forw));
assert(succeeded, "must succeed to push to task queue");
- } else {
- assert(oopDesc::unsafe_equals(oldval, forw), "other thread must have punched the same forwarded oop");
}
+ }
+ assert(! oopDesc::unsafe_equals(obj, forw) || _heap->cancelled_concgc(), "must be evacuated");
+ // Update reference.
+ oopDesc::encode_store_heap_oop_not_null(p, forw);
obj = forw; // For matrix update below.
}
// TODO: Make this templated
if (update_matrix) {
#ifdef ASSERT
< prev index next >