< prev index next >

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

Print this page
rev 53044 : Concurrent stringtable processing

@@ -23,10 +23,13 @@
 
 #include "precompiled.hpp"
 
 #include "classfile/classLoaderData.hpp"
 #include "classfile/classLoaderDataGraph.hpp"
+#include "classfile/stringTable.hpp"
+#include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/parallelCleaning.hpp"
 #include "gc/shared/referenceProcessor.hpp"
 #include "gc/shared/referenceProcessorPhaseTimes.hpp"
 #include "gc/shared/workgroup.hpp"
 #include "gc/shared/weakProcessor.hpp"
 #include "gc/shared/weakProcessor.inline.hpp"

@@ -579,10 +582,29 @@
   if (!_heap->cancelled_gc() && ShenandoahPreclean && _heap->process_references()) {
     preclean_weak_refs();
   }
 }
 
+class ShenandoahTraversalFixRootsClosure : public OopClosure {
+private:
+  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);
+      oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
+      if (!oopDesc::equals_raw(obj, forw)) {
+        RawAccess<IS_NOT_NULL>::oop_store(p, forw);
+      }
+    }
+  }
+
+public:
+  inline void do_oop(oop* p) { do_oop_work(p); }
+  inline void do_oop(narrowOop* p) { do_oop_work(p); }
+};
+
 void ShenandoahTraversalGC::final_traversal_collection() {
   _heap->make_parsable(true);
 
   if (!_heap->cancelled_gc()) {
 #if defined(COMPILER2) || INCLUDE_JVMCI

@@ -606,13 +628,20 @@
 
   if (!_heap->cancelled_gc() && _heap->process_references()) {
     weak_refs_work();
   }
 
-  if (!_heap->cancelled_gc() && _heap->unload_classes()) {
+  if (!_heap->cancelled_gc()) {
+    if (_heap->unload_classes()) {
     _heap->unload_classes_and_cleanup_tables(false);
     fixup_roots();
+    } else {
+      ShenandoahIsAliveClosure is_alive;
+      StringDedupUnlinkOrOopsDoClosure dedup_cl(&is_alive, NULL);
+      StringCleaningTask task(&is_alive, StringDedup::is_enabled() ? &dedup_cl : NULL, true);
+      _heap->workers()->run_task(&task);
+    }
   }
 
   if (!_heap->cancelled_gc()) {
     assert(_task_queues->is_empty(), "queues must be empty after traversal GC");
     TASKQUEUE_STATS_ONLY(_task_queues->print_taskqueue_stats());

@@ -674,29 +703,10 @@
       Universe::verify();
     }
   }
 }
 
-class ShenandoahTraversalFixRootsClosure : public OopClosure {
-private:
-  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);
-      oop forw = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
-      if (!oopDesc::equals_raw(obj, forw)) {
-        RawAccess<IS_NOT_NULL>::oop_store(p, forw);
-      }
-    }
-  }
-
-public:
-  inline void do_oop(oop* p) { do_oop_work(p); }
-  inline void do_oop(narrowOop* p) { do_oop_work(p); }
-};
-
 class ShenandoahTraversalFixRootsTask : public AbstractGangTask {
 private:
   ShenandoahRootProcessor* _rp;
 
 public:
< prev index next >