< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahTraversalGC.cpp

Print this page

        

@@ -194,14 +194,10 @@
         ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::CodeCacheRoots, worker_id);
         _cset_coderoots->possibly_parallel_blobs_do(&code_cl);
       } else {
         _rp->process_all_roots(&roots_cl, &cld_cl, &code_cl, NULL, worker_id);
       }
-      if (ShenandoahStringDedup::is_enabled()) {
-        AlwaysTrueClosure is_alive;
-        ShenandoahStringDedup::parallel_oops_do(&is_alive, &roots_cl, worker_id);
-      }
     }
   }
 };
 
 class ShenandoahConcurrentTraversalCollectionTask : public AbstractGangTask {

@@ -597,14 +593,15 @@
   if (!_heap->cancelled_gc() && _heap->process_references()) {
     weak_refs_work();
   }
 
   if (!_heap->cancelled_gc()) {
-    fixup_roots();
     if (_heap->unload_classes()) {
       _heap->unload_classes_and_cleanup_tables(false);
     }
+
+    fixup_roots();
   }
 
   if (!_heap->cancelled_gc()) {
     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
     TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());

@@ -770,10 +767,33 @@
 
   void do_oop(narrowOop* p) { do_oop_work(p); }
   void do_oop(oop* p)       { do_oop_work(p); }
 };
 
+class ShenandoahTraversalWeakUpdateClosure : public OopClosure {
+private:
+  template <class T>
+  inline void do_oop_work(T* p) {
+    // Cannot call maybe_update_with_forwarded, because on traversal-degen
+    // path the collection set is already dropped. Instead, do the unguarded store.
+    // TODO: This can be fixed after degen-traversal stops dropping cset.
+    T o = RawAccess<>::oop_load(p);
+    if (!CompressedOops::is_null(o)) {
+      oop obj = CompressedOops::decode_not_null(o);
+      obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
+      shenandoah_assert_marked(p, obj);
+      RawAccess<IS_NOT_NULL>::oop_store(p, obj);
+    }
+  }
+
+public:
+  ShenandoahTraversalWeakUpdateClosure() {}
+
+  void do_oop(narrowOop* p) { do_oop_work(p); }
+  void do_oop(oop* p)       { do_oop_work(p); }
+};
+
 class ShenandoahTraversalKeepAliveUpdateDegenClosure : public OopClosure {
 private:
   ShenandoahObjToScanQueue* _queue;
   Thread* _thread;
   ShenandoahTraversalGC* _traversal_gc;

@@ -1082,8 +1102,18 @@
     rp->process_discovered_references(&is_alive, &keep_alive,
                                       &complete_gc, &executor,
                                       &pt);
   }
 
+  {
+    ShenandoahGCPhase phase(phase_process);
+    ShenandoahTerminationTracker termination(ShenandoahPhaseTimings::weakrefs_termination);
+
+    // Process leftover weak oops (using parallel version)
+    ShenandoahTraversalWeakUpdateClosure cl;
+    WeakProcessor::weak_oops_do(workers, &is_alive, &cl, 1);
+
   pt.print_all_references();
+
   assert(task_queues()->is_empty() || _heap->cancelled_gc(), "Should be empty");
+  }
 }
< prev index next >