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