< prev index next >

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

Print this page

        

@@ -31,11 +31,11 @@
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "memory/iterator.hpp"
 #include "oops/access.hpp"
 #include "oops/compressedOops.hpp"
 
-template <bool EVAC, bool ENQUEUE>
+template <bool HAS_FWD, bool EVAC, bool ENQUEUE>
 class ShenandoahUpdateRefsForOopClosure: public BasicOopIterateClosure {
 private:
   ShenandoahHeap* const _heap;
   ShenandoahBarrierSet* const _bs;
   const ShenandoahCollectionSet* const _cset;

@@ -44,22 +44,22 @@
   template <class T>
   inline void do_oop_work(T* p) {
     T o = RawAccess<>::oop_load(p);
     if (!CompressedOops::is_null(o)) {
       oop obj = CompressedOops::decode_not_null(o);
-      if (_cset->is_in(obj)) {
+      if (HAS_FWD && _cset->is_in(obj)) {
         oop fwd = _bs->resolve_forwarded_not_null(obj);
         if (EVAC && obj == fwd) {
           fwd = _heap->evacuate_object(obj, _thread);
         }
-        if (ENQUEUE) {
-          _bs->enqueue(fwd);
-        }
         assert(obj != fwd || _heap->cancelled_gc(), "must be forwarded");
         ShenandoahHeap::cas_oop(fwd, p, o);
+        obj = fwd;
+      }
+      if (ENQUEUE) {
+        _bs->enqueue(obj);
       }
-
     }
   }
 public:
   ShenandoahUpdateRefsForOopClosure() :
           _heap(ShenandoahHeap::heap()),

@@ -72,29 +72,36 @@
   virtual void do_oop(narrowOop* p) { do_oop_work(p); }
 };
 
 void ShenandoahBarrierSet::clone_barrier(oop obj) {
   assert(ShenandoahCloneBarrier, "only get here with clone barriers enabled");
-  assert(_heap->has_forwarded_objects(), "only when heap is unstable");
 
   // This is called for cloning an object (see jvm.cpp) after the clone
   // has been made. We are not interested in any 'previous value' because
   // it would be NULL in any case. But we *are* interested in any oop*
   // that potentially need to be updated.
 
   shenandoah_assert_correct(NULL, obj);
+  if (_heap->is_concurrent_mark_in_progress() &&
+      ShenandoahStoreValEnqueueBarrier) {
+    ShenandoahUpdateRefsForOopClosure<false, false, true> cl;
+    obj->oop_iterate(&cl);
+    return;
+  }
+
   if (skip_bulk_update(cast_from_oop<HeapWord*>(obj))) return;
   if (_heap->is_evacuation_in_progress()) {
     ShenandoahEvacOOMScope evac_scope;
-    ShenandoahUpdateRefsForOopClosure</* evac = */ true, /* enqueue */ false> cl;
+    ShenandoahUpdateRefsForOopClosure</* has_fwd = */ true, /* evac = */ true, /* enqueue */ false> cl;
     obj->oop_iterate(&cl);
   } else if (_heap->is_concurrent_traversal_in_progress()) {
     ShenandoahEvacOOMScope evac_scope;
-    ShenandoahUpdateRefsForOopClosure</* evac = */ true, /* enqueue */ true> cl;
+    ShenandoahUpdateRefsForOopClosure</* has_fwd = */ true, /* evac = */ true, /* enqueue */ true> cl;
     obj->oop_iterate(&cl);
   } else {
-    ShenandoahUpdateRefsForOopClosure</* evac = */ false, /* enqueue */ false> cl;
+    assert(_heap->has_forwarded_objects(), "only with forwarded objects");
+    ShenandoahUpdateRefsForOopClosure</* has_fwd = */ true, /* evac = */ false, /* enqueue */ false> cl;
     obj->oop_iterate(&cl);
   }
 }
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHBARRIERSETCLONE_INLINE_HPP
< prev index next >