< prev index next >

src/share/vm/gc_implementation/shenandoah/shenandoahRootProcessor.cpp

Print this page
rev 10493 : [Backport] Shenandoah string deduplication
rev 10593 : Move JNI Weak References workaround to Shenandoah-specific root processor
rev 10594 : [backport] Split write barrier paths for mutator and GC workers

@@ -31,10 +31,11 @@
 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc_implementation/shenandoah/shenandoahFreeSet.hpp"
 #include "gc_implementation/shenandoah/shenandoahBarrierSet.hpp"
 #include "gc_implementation/shenandoah/shenandoahCollectorPolicy.hpp"
 #include "gc_implementation/shenandoah/shenandoahPhaseTimings.hpp"
+#include "gc_implementation/shenandoah/shenandoahStringDedup.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/fprofiler.hpp"
 #include "runtime/mutex.hpp"
 #include "services/management.hpp"
 

@@ -47,10 +48,14 @@
   _om_iterator(ObjectSynchronizer::parallel_iterator())
 {
   heap->phase_timings()->record_workers_start(_phase);
   _process_strong_tasks->set_n_threads(n_workers);
   heap->set_par_threads(n_workers);
+
+  if (ShenandoahStringDedup::is_enabled()) {
+    ShenandoahStringDedup::clear_claimed();
+  }
 }
 
 ShenandoahRootProcessor::~ShenandoahRootProcessor() {
   delete _process_strong_tasks;
   ShenandoahHeap::heap()->phase_timings()->record_workers_end(_phase);

@@ -72,10 +77,14 @@
   JNIHandles::weak_oops_do(&always_true, oops);
   ObjectSynchronizer::oops_do(oops);
   SystemDictionary::roots_oops_do(oops, oops);
   StringTable::oops_do(oops);
 
+  if (ShenandoahStringDedup::is_enabled()) {
+    ShenandoahStringDedup::oops_do_slow(oops);
+  }
+
   // Do thread roots the last. This allows verification code to find
   // any broken objects from those special roots first, not the accidental
   // dangling reference from the thread root.
   Threads::possibly_parallel_oops_do(oops, &clds, &blobs);
 }

@@ -140,11 +149,13 @@
 void ShenandoahRootProcessor::process_vm_roots(OopClosure* strong_roots,
                                                OopClosure* weak_roots,
                                                OopClosure* jni_weak_roots,
                                                uint worker_id)
 {
-  ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
+  ShenandoahHeap* heap = ShenandoahHeap::heap();
+
+  ShenandoahWorkerTimings* worker_times = heap->phase_timings()->worker_times();
   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_Universe_oops_do)) {
     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::UniverseRoots, worker_id);
     Universe::oops_do(strong_roots);
   }
 

@@ -167,18 +178,33 @@
   }
   if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_SystemDictionary_oops_do)) {
     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::SystemDictionaryRoots, worker_id);
     SystemDictionary::roots_oops_do(strong_roots, weak_roots);
   }
+
+  // Note: Workaround bugs with JNI weak reference handling during concurrent cycles,
+  // by pessimistically assuming all JNI weak refs are alive. Achieve this by passing
+  // stronger closure, where weaker one would suffice otherwise. This effectively makes
+  // JNI weak refs non-reclaimable by concurrent GC, but they would be reclaimed by
+  // STW GCs, that are not affected by the bug, nevertheless.
+  if (!heap->is_full_gc_in_progress() && !heap->is_degenerated_gc_in_progress()) {
+    jni_weak_roots = strong_roots;
+  }
+
   if (jni_weak_roots != NULL) {
     if (!_process_strong_tasks->is_task_claimed(SHENANDOAH_RP_PS_JNIHandles_weak_oops_do)) {
       ShenandoahAlwaysTrueClosure always_true;
       ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::JNIWeakRoots, worker_id);
       JNIHandles::weak_oops_do(&always_true, jni_weak_roots);
     }
   }
 
+  if (ShenandoahStringDedup::is_enabled() && weak_roots != NULL) {
+    ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::StringDedupRoots, worker_id);
+    ShenandoahStringDedup::parallel_oops_do(weak_roots);
+  }
+
   {
     ShenandoahWorkerTimingsTracker timer(worker_times, ShenandoahPhaseTimings::ObjectSynchronizerRoots, worker_id);
     if (ShenandoahFastSyncRoots && MonitorInUseLists) {
       ObjectSynchronizer::oops_do(strong_roots);
     } else {

@@ -224,11 +250,10 @@
     // SLT thread. We make additional effort to recover from that OOME in SLT,
     // see ShenandoahHeap::oom_during_evacuation(). It seems to be the lesser evil
     // to do there, because we cannot trigger Full GC right here, when we are
     // in another VMOperation.
 
-    ShenandoahEvacOOMScopeLeaver leaver;
     oop pll = java_lang_ref_Reference::pending_list_lock();
     oopDesc::bs()->write_barrier(pll);
   }
 
   ShenandoahWorkerTimings* worker_times = ShenandoahHeap::heap()->phase_timings()->worker_times();
< prev index next >