< prev index next >

src/share/vm/classfile/symbolTable.cpp

Print this page

        

@@ -719,11 +719,11 @@
 static void ensure_string_alive(oop string) {
   // A lookup in the StringTable could return an object that was previously
   // considered dead. The SATB part of G1 needs to get notified about this
   // potential resurrection, otherwise the marking might not find the object.
 #if INCLUDE_ALL_GCS
-  if (UseG1GC && string != NULL) {
+  if ((UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) && string != NULL) {
     G1SATBCardTableModRefBS::enqueue(string);
   }
 #endif
 }
 

@@ -924,10 +924,32 @@
     int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
     buckets_oops_do(f, start_idx, end_idx);
   }
 }
 
+void StringTable::possibly_parallel_oops_do_shenandoah(OopClosure* f) {
+  const int limit = the_table()->table_size();
+
+  // ClaimChunkSize is too small for processing a String table during the pause
+  // efficiently: the atomic add costs dominate on many reasonable string tables.
+  // Recast the chunk size to give each GC worker about 10 chunks.
+  assert(UseShenandoahGC, "Only for Shenandoah");
+  const int chunk_size = MAX2<int>(ClaimChunkSize, limit / (ParallelGCThreads * 10));
+
+  for (;;) {
+    // Grab next set of buckets to scan
+    int start_idx = Atomic::add(chunk_size, &_parallel_claimed_idx) - chunk_size;
+    if (start_idx >= limit) {
+      // End of table
+      break;
+    }
+
+    int end_idx = MIN2(limit, start_idx + chunk_size);
+    buckets_oops_do(f, start_idx, end_idx);
+  }
+}
+
 // This verification is part of Universe::verify() and needs to be quick.
 // See StringTable::verify_and_compare() below for exhaustive verification.
 void StringTable::verify() {
   for (int i = 0; i < the_table()->table_size(); ++i) {
     HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
< prev index next >