src/share/vm/memory/sharedHeap.cpp

Print this page
rev 4735 : 8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets.
Reviewed-by:

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -44,11 +44,10 @@
   SH_PS_ObjectSynchronizer_oops_do,
   SH_PS_FlatProfiler_oops_do,
   SH_PS_Management_oops_do,
   SH_PS_SystemDictionary_oops_do,
   SH_PS_jvmti_oops_do,
-  SH_PS_StringTable_oops_do,
   SH_PS_CodeCache_oops_do,
   // Leave this one last.
   SH_PS_NumElements
 };
 

@@ -124,10 +123,12 @@
 SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* outer, bool activate)
   : MarkScope(activate)
 {
   if (_active) {
     outer->change_strong_roots_parity();
+    // Zero the claimed high water mark in the StringTable
+    StringTable::clear_par_claimed_index();
   }
 }
 
 SharedHeap::StrongRootsScope::~StrongRootsScope() {
   // nothing particular

@@ -136,11 +137,12 @@
 void SharedHeap::process_strong_roots(bool activate_scope,
                                       bool is_scavenging,
                                       ScanningOption so,
                                       OopClosure* roots,
                                       CodeBlobClosure* code_roots,
-                                      KlassClosure* klass_closure) {
+                                      KlassClosure* klass_closure,
+                                      uint worker_id) {
   StrongRootsScope srs(this, activate_scope);
 
   // General strong roots.
   assert(_strong_roots_parity != 0, "must have called prologue code");
   // _n_termination for _process_strong_tasks should be set up stream

@@ -151,18 +153,20 @@
     Universe::oops_do(roots);
   }
   // Global (strong) JNI handles
   if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do))
     JNIHandles::oops_do(roots);
+
   // All threads execute this; the individual threads are task groups.
   CLDToOopClosure roots_from_clds(roots);
   CLDToOopClosure* roots_from_clds_p = (is_scavenging ? NULL : &roots_from_clds);
-  if (ParallelGCThreads > 0) {
+  if (CollectedHeap::use_parallel_gc_threads()) {
     Threads::possibly_parallel_oops_do(roots, roots_from_clds_p ,code_roots);
   } else {
     Threads::oops_do(roots, roots_from_clds_p, code_roots);
   }
+
   if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do))
     ObjectSynchronizer::oops_do(roots);
   if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do))
     FlatProfiler::oops_do(roots);
   if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do))

@@ -180,12 +184,17 @@
     } else {
       fatal("We should always have selected either SO_AllClasses or SO_SystemClasses");
     }
   }
 
-  if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
+  // All threads execute the following. A specific chunk of buckets
+  // from the StringTable are the individual tasks.
     if (so & SO_Strings) {
+    if (CollectedHeap::use_parallel_gc_threads()) {
+      StringTable::possibly_parallel_oops_do(roots, worker_id);
+    } else {
+      assert(worker_id == 0, "only worker 0 for serial work");
       StringTable::oops_do(roots);
     }
   }
 
   if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) {