changeset 7311:f0c015238101

6979279: remove special-case code for ParallelGCThreads==0 Reviewed-by: jwilhelm, brutisso, kbarrett
author mlarsson
date Tue, 21 Oct 2014 11:57:22 +0200
parents 96e85e97d06e
children 42667d44d63d
files src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp src/share/vm/gc_implementation/g1/concurrentMark.cpp src/share/vm/gc_implementation/g1/concurrentMark.hpp src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp src/share/vm/gc_implementation/g1/g1HotCardCache.cpp src/share/vm/gc_implementation/g1/g1RemSet.cpp src/share/vm/gc_implementation/g1/g1RemSet.hpp src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp src/share/vm/gc_implementation/g1/g1StringDedup.cpp src/share/vm/gc_implementation/g1/satbQueue.cpp src/share/vm/gc_implementation/g1/satbQueue.hpp src/share/vm/gc_implementation/parNew/parNewGeneration.cpp src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp src/share/vm/memory/freeBlockDictionary.cpp src/share/vm/memory/freeList.cpp src/share/vm/memory/freeList.hpp src/share/vm/memory/sharedHeap.cpp
diffstat 22 files changed, 343 insertions(+), 659 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -64,23 +64,6 @@
   set_hint(hint);
 }
 
-#ifndef PRODUCT
-template <class Chunk>
-void AdaptiveFreeList<Chunk>::assert_proper_lock_protection_work() const {
-  assert(protecting_lock() != NULL, "Don't call this directly");
-  assert(ParallelGCThreads > 0, "Don't call this directly");
-  Thread* thr = Thread::current();
-  if (thr->is_VM_thread() || thr->is_ConcurrentGC_thread()) {
-    // assert that we are holding the freelist lock
-  } else if (thr->is_GC_task_thread()) {
-    assert(protecting_lock()->owned_by_self(), "FreeList RACE DETECTED");
-  } else if (thr->is_Java_thread()) {
-    assert(!SafepointSynchronize::is_at_safepoint(), "Should not be executing");
-  } else {
-    ShouldNotReachHere();  // unaccounted thread type?
-  }
-}
-#endif
 template <class Chunk>
 void AdaptiveFreeList<Chunk>::init_statistics(bool split_birth) {
   _allocation_stats.initialize(split_birth);
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/adaptiveFreeList.hpp	Tue Oct 21 11:57:22 2014 +0200
@@ -81,8 +81,6 @@
   // Reset the head, tail, hint, and count of a free list.
   void reset(size_t hint);
 
-  void assert_proper_lock_protection_work() const PRODUCT_RETURN;
-
   void print_on(outputStream* st, const char* c = NULL) const;
 
   size_t hint() const {
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -149,18 +149,15 @@
   check_free_list_consistency();
 
   // Initialize locks for parallel case.
-
-  if (CollectedHeap::use_parallel_gc_threads()) {
-    for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
-      _indexedFreeListParLocks[i] = new Mutex(Mutex::leaf - 1, // == ExpandHeap_lock - 1
-                                              "a freelist par lock",
-                                              true);
-      DEBUG_ONLY(
-        _indexedFreeList[i].set_protecting_lock(_indexedFreeListParLocks[i]);
-      )
-    }
-    _dictionary->set_par_lock(&_parDictionaryAllocLock);
+  for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
+    _indexedFreeListParLocks[i] = new Mutex(Mutex::leaf - 1, // == ExpandHeap_lock - 1
+                                            "a freelist par lock",
+                                            true);
+    DEBUG_ONLY(
+      _indexedFreeList[i].set_protecting_lock(_indexedFreeListParLocks[i]);
+    )
   }
+  _dictionary->set_par_lock(&_parDictionaryAllocLock);
 }
 
 // Like CompactibleSpace forward() but always calls cross_threshold() to
@@ -622,17 +619,11 @@
         // Mark the boundary of the new block in BOT
         _bt.mark_block(prevEnd, value);
         // put it all in the linAB
-        if (ParallelGCThreads == 0) {
-          _smallLinearAllocBlock._ptr = prevEnd;
-          _smallLinearAllocBlock._word_size = newFcSize;
-          repairLinearAllocBlock(&_smallLinearAllocBlock);
-        } else { // ParallelGCThreads > 0
-          MutexLockerEx x(parDictionaryAllocLock(),
-                          Mutex::_no_safepoint_check_flag);
-          _smallLinearAllocBlock._ptr = prevEnd;
-          _smallLinearAllocBlock._word_size = newFcSize;
-          repairLinearAllocBlock(&_smallLinearAllocBlock);
-        }
+        MutexLockerEx x(parDictionaryAllocLock(),
+                        Mutex::_no_safepoint_check_flag);
+        _smallLinearAllocBlock._ptr = prevEnd;
+        _smallLinearAllocBlock._word_size = newFcSize;
+        repairLinearAllocBlock(&_smallLinearAllocBlock);
         // Births of chunks put into a LinAB are not recorded.  Births
         // of chunks as they are allocated out of a LinAB are.
       } else {
@@ -1740,10 +1731,7 @@
   assert(chunk != NULL && is_in_reserved(chunk), "Not in this space!");
   // One of the parallel gc task threads may be here
   // whilst others are allocating.
-  Mutex* lock = NULL;
-  if (ParallelGCThreads != 0) {
-    lock = &_parDictionaryAllocLock;
-  }
+  Mutex* lock = &_parDictionaryAllocLock;
   FreeChunk* ec;
   {
     MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag);
@@ -1760,7 +1748,7 @@
   }
   ec->set_size(size);
   debug_only(ec->mangleFreed(size));
-  if (size < SmallForDictionary && ParallelGCThreads != 0) {
+  if (size < SmallForDictionary) {
     lock = _indexedFreeListParLocks[size];
   }
   MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag);
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -887,10 +887,8 @@
   // along with all the other pointers into the heap but
   // compaction is expected to be a rare event with
   // a heap using cms so don't do it without seeing the need.
-  if (CollectedHeap::use_parallel_gc_threads()) {
-    for (uint i = 0; i < ParallelGCThreads; i++) {
-      _par_gc_thread_states[i]->promo.reset();
-    }
+  for (uint i = 0; i < ParallelGCThreads; i++) {
+    _par_gc_thread_states[i]->promo.reset();
   }
 }
 
@@ -2804,10 +2802,8 @@
   collector()->gc_epilogue(full);
 
   // Also reset promotion tracking in par gc thread states.
-  if (CollectedHeap::use_parallel_gc_threads()) {
-    for (uint i = 0; i < ParallelGCThreads; i++) {
-      _par_gc_thread_states[i]->promo.stopTrackingPromotions(i);
-    }
+  for (uint i = 0; i < ParallelGCThreads; i++) {
+    _par_gc_thread_states[i]->promo.stopTrackingPromotions(i);
   }
 }
 
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -612,74 +612,64 @@
             ConcGCThreads, ParallelGCThreads);
     return;
   }
-  if (ParallelGCThreads == 0) {
-    // if we are not running with any parallel GC threads we will not
-    // spawn any marking threads either
-    _parallel_marking_threads =       0;
-    _max_parallel_marking_threads =   0;
-    _sleep_factor             =     0.0;
-    _marking_task_overhead    =     1.0;
+  if (!FLAG_IS_DEFAULT(ConcGCThreads) && ConcGCThreads > 0) {
+    // Note: ConcGCThreads has precedence over G1MarkingOverheadPercent
+    // if both are set
+    _sleep_factor             = 0.0;
+    _marking_task_overhead    = 1.0;
+  } else if (G1MarkingOverheadPercent > 0) {
+    // We will calculate the number of parallel marking threads based
+    // on a target overhead with respect to the soft real-time goal
+    double marking_overhead = (double) G1MarkingOverheadPercent / 100.0;
+    double overall_cm_overhead =
+      (double) MaxGCPauseMillis * marking_overhead /
+      (double) GCPauseIntervalMillis;
+    double cpu_ratio = 1.0 / (double) os::processor_count();
+    double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio);
+    double marking_task_overhead =
+      overall_cm_overhead / marking_thread_num *
+                                              (double) os::processor_count();
+    double sleep_factor =
+                       (1.0 - marking_task_overhead) / marking_task_overhead;
+
+    FLAG_SET_ERGO(uintx, ConcGCThreads, (uint) marking_thread_num);
+    _sleep_factor             = sleep_factor;
+    _marking_task_overhead    = marking_task_overhead;
   } else {
-    if (!FLAG_IS_DEFAULT(ConcGCThreads) && ConcGCThreads > 0) {
-      // Note: ConcGCThreads has precedence over G1MarkingOverheadPercent
-      // if both are set
-      _sleep_factor             = 0.0;
-      _marking_task_overhead    = 1.0;
-    } else if (G1MarkingOverheadPercent > 0) {
-      // We will calculate the number of parallel marking threads based
-      // on a target overhead with respect to the soft real-time goal
-      double marking_overhead = (double) G1MarkingOverheadPercent / 100.0;
-      double overall_cm_overhead =
-        (double) MaxGCPauseMillis * marking_overhead /
-        (double) GCPauseIntervalMillis;
-      double cpu_ratio = 1.0 / (double) os::processor_count();
-      double marking_thread_num = ceil(overall_cm_overhead / cpu_ratio);
-      double marking_task_overhead =
-        overall_cm_overhead / marking_thread_num *
-                                                (double) os::processor_count();
-      double sleep_factor =
-                         (1.0 - marking_task_overhead) / marking_task_overhead;
-
-      FLAG_SET_ERGO(uintx, ConcGCThreads, (uint) marking_thread_num);
-      _sleep_factor             = sleep_factor;
-      _marking_task_overhead    = marking_task_overhead;
-    } else {
-      // Calculate the number of parallel marking threads by scaling
-      // the number of parallel GC threads.
-      uint marking_thread_num = scale_parallel_threads((uint) ParallelGCThreads);
-      FLAG_SET_ERGO(uintx, ConcGCThreads, marking_thread_num);
-      _sleep_factor             = 0.0;
-      _marking_task_overhead    = 1.0;
-    }
-
-    assert(ConcGCThreads > 0, "Should have been set");
-    _parallel_marking_threads = (uint) ConcGCThreads;
-    _max_parallel_marking_threads = _parallel_marking_threads;
-
-    if (parallel_marking_threads() > 1) {
-      _cleanup_task_overhead = 1.0;
-    } else {
-      _cleanup_task_overhead = marking_task_overhead();
-    }
-    _cleanup_sleep_factor =
-                     (1.0 - cleanup_task_overhead()) / cleanup_task_overhead();
+    // Calculate the number of parallel marking threads by scaling
+    // the number of parallel GC threads.
+    uint marking_thread_num = scale_parallel_threads((uint) ParallelGCThreads);
+    FLAG_SET_ERGO(uintx, ConcGCThreads, marking_thread_num);
+    _sleep_factor             = 0.0;
+    _marking_task_overhead    = 1.0;
+  }
+
+  assert(ConcGCThreads > 0, "Should have been set");
+  _parallel_marking_threads = (uint) ConcGCThreads;
+  _max_parallel_marking_threads = _parallel_marking_threads;
+
+  if (parallel_marking_threads() > 1) {
+    _cleanup_task_overhead = 1.0;
+  } else {
+    _cleanup_task_overhead = marking_task_overhead();
+  }
+  _cleanup_sleep_factor =
+                   (1.0 - cleanup_task_overhead()) / cleanup_task_overhead();
 
 #if 0
-    gclog_or_tty->print_cr("Marking Threads          %d", parallel_marking_threads());
-    gclog_or_tty->print_cr("CM Marking Task Overhead %1.4lf", marking_task_overhead());
-    gclog_or_tty->print_cr("CM Sleep Factor          %1.4lf", sleep_factor());
-    gclog_or_tty->print_cr("CL Marking Task Overhead %1.4lf", cleanup_task_overhead());
-    gclog_or_tty->print_cr("CL Sleep Factor          %1.4lf", cleanup_sleep_factor());
+  gclog_or_tty->print_cr("Marking Threads          %d", parallel_marking_threads());
+  gclog_or_tty->print_cr("CM Marking Task Overhead %1.4lf", marking_task_overhead());
+  gclog_or_tty->print_cr("CM Sleep Factor          %1.4lf", sleep_factor());
+  gclog_or_tty->print_cr("CL Marking Task Overhead %1.4lf", cleanup_task_overhead());
+  gclog_or_tty->print_cr("CL Sleep Factor          %1.4lf", cleanup_sleep_factor());
 #endif
 
-    guarantee(parallel_marking_threads() > 0, "peace of mind");
-    _parallel_workers = new FlexibleWorkGang("G1 Parallel Marking Threads",
-         _max_parallel_marking_threads, false, true);
-    if (_parallel_workers == NULL) {
-      vm_exit_during_initialization("Failed necessary allocation.");
-    } else {
-      _parallel_workers->initialize_workers();
-    }
+  _parallel_workers = new FlexibleWorkGang("G1 Parallel Marking Threads",
+       _max_parallel_marking_threads, false, true);
+  if (_parallel_workers == NULL) {
+    vm_exit_during_initialization("Failed necessary allocation.");
+  } else {
+    _parallel_workers->initialize_workers();
   }
 
   if (FLAG_IS_DEFAULT(MarkStackSize)) {
@@ -1167,29 +1157,23 @@
 // Calculates the number of active workers for a concurrent
 // phase.
 uint ConcurrentMark::calc_parallel_marking_threads() {
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    uint n_conc_workers = 0;
-    if (!UseDynamicNumberOfGCThreads ||
-        (!FLAG_IS_DEFAULT(ConcGCThreads) &&
-         !ForceDynamicNumberOfGCThreads)) {
-      n_conc_workers = max_parallel_marking_threads();
-    } else {
-      n_conc_workers =
-        AdaptiveSizePolicy::calc_default_active_workers(
-                                     max_parallel_marking_threads(),
-                                     1, /* Minimum workers */
-                                     parallel_marking_threads(),
-                                     Threads::number_of_non_daemon_threads());
-      // Don't scale down "n_conc_workers" by scale_parallel_threads() because
-      // that scaling has already gone into "_max_parallel_marking_threads".
-    }
-    assert(n_conc_workers > 0, "Always need at least 1");
-    return n_conc_workers;
+  uint n_conc_workers = 0;
+  if (!UseDynamicNumberOfGCThreads ||
+      (!FLAG_IS_DEFAULT(ConcGCThreads) &&
+       !ForceDynamicNumberOfGCThreads)) {
+    n_conc_workers = max_parallel_marking_threads();
+  } else {
+    n_conc_workers =
+      AdaptiveSizePolicy::calc_default_active_workers(
+                                   max_parallel_marking_threads(),
+                                   1, /* Minimum workers */
+                                   parallel_marking_threads(),
+                                   Threads::number_of_non_daemon_threads());
+    // Don't scale down "n_conc_workers" by scale_parallel_threads() because
+    // that scaling has already gone into "_max_parallel_marking_threads".
   }
-  // If we are not running with any parallel GC threads we will not
-  // have spawned any marking threads either. Hence the number of
-  // concurrent workers should be 0.
-  return 0;
+  assert(n_conc_workers > 0, "Always need at least 1");
+  return n_conc_workers;
 }
 
 void ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) {
@@ -1244,12 +1228,8 @@
     uint active_workers = MAX2(1U, parallel_marking_threads());
 
     CMRootRegionScanTask task(this);
-    if (use_parallel_marking_threads()) {
-      _parallel_workers->set_active_workers((int) active_workers);
-      _parallel_workers->run_task(&task);
-    } else {
-      task.work(0);
-    }
+    _parallel_workers->set_active_workers(active_workers);
+    _parallel_workers->run_task(&task);
 
     // It's possible that has_aborted() is true here without actually
     // aborting the survivor scan earlier. This is OK as it's
@@ -1280,15 +1260,11 @@
   set_concurrency_and_phase(active_workers, true /* concurrent */);
 
   CMConcurrentMarkingTask markingTask(this, cmThread());
-  if (use_parallel_marking_threads()) {
-    _parallel_workers->set_active_workers((int)active_workers);
-    // Don't set _n_par_threads because it affects MT in process_roots()
-    // and the decisions on that MT processing is made elsewhere.
-    assert(_parallel_workers->active_workers() > 0, "Should have been set");
-    _parallel_workers->run_task(&markingTask);
-  } else {
-    markingTask.work(0);
-  }
+  _parallel_workers->set_active_workers(active_workers);
+  // Don't set _n_par_threads because it affects MT in process_roots()
+  // and the decisions on that MT processing is made elsewhere.
+  assert(_parallel_workers->active_workers() > 0, "Should have been set");
+  _parallel_workers->run_task(&markingTask);
   print_stats();
 }
 
@@ -1715,11 +1691,7 @@
                                             _expected_card_bm,
                                             _verbose);
 
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer);
-    } else {
-      _g1h->heap_region_iterate(&verify_cl);
-    }
+    _g1h->heap_region_par_iterate(&verify_cl, worker_id, &_hrclaimer);
 
     Atomic::add(verify_cl.failures(), &_failures);
   }
@@ -1822,11 +1794,7 @@
                                                 _actual_region_bm,
                                                 _actual_card_bm);
 
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      _g1h->heap_region_par_iterate(&final_update_cl, worker_id, &_hrclaimer);
-    } else {
-      _g1h->heap_region_iterate(&final_update_cl);
-    }
+    _g1h->heap_region_par_iterate(&final_update_cl, worker_id, &_hrclaimer);
   }
 };
 
@@ -1923,11 +1891,7 @@
     HRRSCleanupTask hrrs_cleanup_task;
     G1NoteEndOfConcMarkClosure g1_note_end(_g1h, &local_cleanup_list,
                                            &hrrs_cleanup_task);
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      _g1h->heap_region_par_iterate(&g1_note_end, worker_id, &_hrclaimer);
-    } else {
-      _g1h->heap_region_iterate(&g1_note_end);
-    }
+    _g1h->heap_region_par_iterate(&g1_note_end, worker_id, &_hrclaimer);
     assert(g1_note_end.complete(), "Shouldn't have yielded!");
 
     // Now update the lists
@@ -1978,11 +1942,7 @@
   }
 
   void work(uint worker_id) {
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      _g1rs->scrub_par(_region_bm, _card_bm, worker_id, &_hrclaimer);
-    } else {
-      _g1rs->scrub(_region_bm, _card_bm);
-    }
+    _g1rs->scrub(_region_bm, _card_bm, worker_id, &_hrclaimer);
   }
 
 };
@@ -2021,18 +1981,13 @@
   // Do counting once more with the world stopped for good measure.
   G1ParFinalCountTask g1_par_count_task(g1h, &_region_bm, &_card_bm);
 
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    g1h->set_par_threads();
-    n_workers = g1h->n_par_threads();
-    assert(g1h->n_par_threads() == n_workers,
-           "Should not have been reset");
-    g1h->workers()->run_task(&g1_par_count_task);
-    // Done with the parallel phase so reset to 0.
-    g1h->set_par_threads(0);
-  } else {
-    n_workers = 1;
-    g1_par_count_task.work(0);
-  }
+  g1h->set_par_threads();
+  n_workers = g1h->n_par_threads();
+  assert(g1h->n_par_threads() == n_workers,
+         "Should not have been reset");
+  g1h->workers()->run_task(&g1_par_count_task);
+  // Done with the parallel phase so reset to 0.
+  g1h->set_par_threads(0);
 
   if (VerifyDuringGC) {
     // Verify that the counting data accumulated during marking matches
@@ -2048,14 +2003,10 @@
                                                  &expected_region_bm,
                                                  &expected_card_bm);
 
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      g1h->set_par_threads((int)n_workers);
-      g1h->workers()->run_task(&g1_par_verify_task);
-      // Done with the parallel phase so reset to 0.
-      g1h->set_par_threads(0);
-    } else {
-      g1_par_verify_task.work(0);
-    }
+    g1h->set_par_threads((int)n_workers);
+    g1h->workers()->run_task(&g1_par_verify_task);
+    // Done with the parallel phase so reset to 0.
+    g1h->set_par_threads(0);
 
     guarantee(g1_par_verify_task.failures() == 0, "Unexpected accounting failures");
   }
@@ -2079,13 +2030,9 @@
 
   // Note end of marking in all heap regions.
   G1ParNoteEndTask g1_par_note_end_task(g1h, &_cleanup_list, n_workers);
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    g1h->set_par_threads((int)n_workers);
-    g1h->workers()->run_task(&g1_par_note_end_task);
-    g1h->set_par_threads(0);
-  } else {
-    g1_par_note_end_task.work(0);
-  }
+  g1h->set_par_threads((int)n_workers);
+  g1h->workers()->run_task(&g1_par_note_end_task);
+  g1h->set_par_threads(0);
   g1h->check_gc_time_stamps();
 
   if (!cleanup_list_is_empty()) {
@@ -2100,13 +2047,9 @@
   if (G1ScrubRemSets) {
     double rs_scrub_start = os::elapsedTime();
     G1ParScrubRemSetTask g1_par_scrub_rs_task(g1h, &_region_bm, &_card_bm, n_workers);
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      g1h->set_par_threads((int)n_workers);
-      g1h->workers()->run_task(&g1_par_scrub_rs_task);
-      g1h->set_par_threads(0);
-    } else {
-      g1_par_scrub_rs_task.work(0);
-    }
+    g1h->set_par_threads((int)n_workers);
+    g1h->workers()->run_task(&g1_par_scrub_rs_task);
+    g1h->set_par_threads(0);
 
     double rs_scrub_end = os::elapsedTime();
     double this_rs_scrub_time = (rs_scrub_end - rs_scrub_start);
@@ -2503,7 +2446,7 @@
     // is not multi-threaded we use the current (VMThread) thread,
     // otherwise we use the work gang from the G1CollectedHeap and
     // we utilize all the worker threads we can.
-    bool processing_is_mt = rp->processing_is_mt() && g1h->workers() != NULL;
+    bool processing_is_mt = rp->processing_is_mt();
     uint active_workers = (processing_is_mt ? g1h->workers()->active_workers() : 1U);
     active_workers = MAX2(MIN2(active_workers, _max_worker_id), 1U);
 
@@ -2622,16 +2565,15 @@
   G1CMOopClosure _cm_cl;
   MarkingCodeBlobClosure _code_cl;
   int _thread_parity;
-  bool _is_par;
 
  public:
-  G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task, bool is_par) :
+  G1RemarkThreadsClosure(G1CollectedHeap* g1h, CMTask* task) :
     _cm_obj(task), _cm_cl(g1h, g1h->concurrent_mark(), task), _code_cl(&_cm_cl, !CodeBlobToOopClosure::FixRelocations),
-    _thread_parity(SharedHeap::heap()->strong_roots_parity()), _is_par(is_par) {}
+    _thread_parity(SharedHeap::heap()->strong_roots_parity()) {}
 
   void do_thread(Thread* thread) {
     if (thread->is_Java_thread()) {
-      if (thread->claim_oops_do(_is_par, _thread_parity)) {
+      if (thread->claim_oops_do(true, _thread_parity)) {
         JavaThread* jt = (JavaThread*)thread;
 
         // In theory it should not be neccessary to explicitly walk the nmethods to find roots for concurrent marking
@@ -2645,7 +2587,7 @@
         jt->satb_mark_queue().apply_closure_and_empty(&_cm_obj);
       }
     } else if (thread->is_VM_thread()) {
-      if (thread->claim_oops_do(_is_par, _thread_parity)) {
+      if (thread->claim_oops_do(true, _thread_parity)) {
         JavaThread::satb_mark_queue_set().shared_satb_queue()->apply_closure_and_empty(&_cm_obj);
       }
     }
@@ -2655,7 +2597,6 @@
 class CMRemarkTask: public AbstractGangTask {
 private:
   ConcurrentMark* _cm;
-  bool            _is_serial;
 public:
   void work(uint worker_id) {
     // Since all available tasks are actually started, we should
@@ -2667,14 +2608,14 @@
         ResourceMark rm;
         HandleMark hm;
 
-        G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task, !_is_serial);
+        G1RemarkThreadsClosure threads_f(G1CollectedHeap::heap(), task);
         Threads::threads_do(&threads_f);
       }
 
       do {
         task->do_marking_step(1000000000.0 /* something very large */,
                               true         /* do_termination       */,
-                              _is_serial);
+                              false        /* is_serial            */);
       } while (task->has_aborted() && !_cm->has_overflown());
       // If we overflow, then we do not want to restart. We instead
       // want to abort remark and do concurrent marking again.
@@ -2682,8 +2623,8 @@
     }
   }
 
-  CMRemarkTask(ConcurrentMark* cm, int active_workers, bool is_serial) :
-    AbstractGangTask("Par Remark"), _cm(cm), _is_serial(is_serial) {
+  CMRemarkTask(ConcurrentMark* cm, int active_workers) :
+    AbstractGangTask("Par Remark"), _cm(cm) {
     _cm->terminator()->reset_for_reuse(active_workers);
   }
 };
@@ -2697,43 +2638,28 @@
 
   g1h->ensure_parsability(false);
 
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    G1CollectedHeap::StrongRootsScope srs(g1h);
-    // this is remark, so we'll use up all active threads
-    uint active_workers = g1h->workers()->active_workers();
-    if (active_workers == 0) {
-      assert(active_workers > 0, "Should have been set earlier");
-      active_workers = (uint) ParallelGCThreads;
-      g1h->workers()->set_active_workers(active_workers);
-    }
-    set_concurrency_and_phase(active_workers, false /* concurrent */);
-    // Leave _parallel_marking_threads at it's
-    // value originally calculated in the ConcurrentMark
-    // constructor and pass values of the active workers
-    // through the gang in the task.
-
-    CMRemarkTask remarkTask(this, active_workers, false /* is_serial */);
-    // We will start all available threads, even if we decide that the
-    // active_workers will be fewer. The extra ones will just bail out
-    // immediately.
-    g1h->set_par_threads(active_workers);
-    g1h->workers()->run_task(&remarkTask);
-    g1h->set_par_threads(0);
-  } else {
-    G1CollectedHeap::StrongRootsScope srs(g1h);
-    uint active_workers = 1;
-    set_concurrency_and_phase(active_workers, false /* concurrent */);
-
-    // Note - if there's no work gang then the VMThread will be
-    // the thread to execute the remark - serially. We have
-    // to pass true for the is_serial parameter so that
-    // CMTask::do_marking_step() doesn't enter the sync
-    // barriers in the event of an overflow. Doing so will
-    // cause an assert that the current thread is not a
-    // concurrent GC thread.
-    CMRemarkTask remarkTask(this, active_workers, true /* is_serial*/);
-    remarkTask.work(0);
+  G1CollectedHeap::StrongRootsScope srs(g1h);
+  // this is remark, so we'll use up all active threads
+  uint active_workers = g1h->workers()->active_workers();
+  if (active_workers == 0) {
+    assert(active_workers > 0, "Should have been set earlier");
+    active_workers = (uint) ParallelGCThreads;
+    g1h->workers()->set_active_workers(active_workers);
   }
+  set_concurrency_and_phase(active_workers, false /* concurrent */);
+  // Leave _parallel_marking_threads at it's
+  // value originally calculated in the ConcurrentMark
+  // constructor and pass values of the active workers
+  // through the gang in the task.
+
+  CMRemarkTask remarkTask(this, active_workers);
+  // We will start all available threads, even if we decide that the
+  // active_workers will be fewer. The extra ones will just bail out
+  // immediately.
+  g1h->set_par_threads(active_workers);
+  g1h->workers()->run_task(&remarkTask);
+  g1h->set_par_threads(0);
+
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
   guarantee(has_overflown() ||
             satb_mq_set.completed_buffers_num() == 0,
@@ -3279,30 +3205,20 @@
   void work(uint worker_id) {
     AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_worker_id);
 
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer);
-    } else {
-      _g1h->heap_region_iterate(&cl);
-    }
+    _g1h->heap_region_par_iterate(&cl, worker_id, &_hrclaimer);
   }
 };
 
 
 void ConcurrentMark::aggregate_count_data() {
-  int n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
-                        _g1h->workers()->active_workers() :
-                        1);
+  int n_workers = _g1h->workers()->active_workers();
 
   G1AggregateCountDataTask g1_par_agg_task(_g1h, this, &_card_bm,
                                            _max_worker_id, n_workers);
 
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    _g1h->set_par_threads(n_workers);
-    _g1h->workers()->run_task(&g1_par_agg_task);
-    _g1h->set_par_threads(0);
-  } else {
-    g1_par_agg_task.work(0);
-  }
+  _g1h->set_par_threads(n_workers);
+  _g1h->workers()->run_task(&g1_par_agg_task);
+  _g1h->set_par_threads(0);
   _g1h->allocation_context_stats().update_at_remark();
 }
 
@@ -3430,9 +3346,7 @@
 }
 
 void ConcurrentMark::print_worker_threads_on(outputStream* st) const {
-  if (use_parallel_marking_threads()) {
-    _parallel_workers->print_worker_threads_on(st);
-  }
+  _parallel_workers->print_worker_threads_on(st);
 }
 
 void ConcurrentMark::print_on_error(outputStream* st) const {
@@ -3953,32 +3867,17 @@
 
   CMObjectClosure oc(this);
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    satb_mq_set.set_par_closure(_worker_id, &oc);
-  } else {
-    satb_mq_set.set_closure(&oc);
-  }
+  satb_mq_set.set_closure(_worker_id, &oc);
 
   // This keeps claiming and applying the closure to completed buffers
   // until we run out of buffers or we need to abort.
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    while (!has_aborted() &&
-           satb_mq_set.par_apply_closure_to_completed_buffer(_worker_id)) {
-      if (_cm->verbose_medium()) {
-        gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id);
-      }
-      statsOnly( ++_satb_buffers_processed );
-      regular_clock_call();
+  while (!has_aborted() &&
+         satb_mq_set.apply_closure_to_completed_buffer(_worker_id)) {
+    if (_cm->verbose_medium()) {
+      gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id);
     }
-  } else {
-    while (!has_aborted() &&
-           satb_mq_set.apply_closure_to_completed_buffer()) {
-      if (_cm->verbose_medium()) {
-        gclog_or_tty->print_cr("[%u] processed an SATB buffer", _worker_id);
-      }
-      statsOnly( ++_satb_buffers_processed );
-      regular_clock_call();
-    }
+    statsOnly( ++_satb_buffers_processed );
+    regular_clock_call();
   }
 
   _draining_satb_buffers = false;
@@ -3987,11 +3886,7 @@
          concurrent() ||
          satb_mq_set.completed_buffers_num() == 0, "invariant");
 
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    satb_mq_set.set_par_closure(_worker_id, NULL);
-  } else {
-    satb_mq_set.set_closure(NULL);
-  }
+  satb_mq_set.set_closure(_worker_id, NULL);
 
   // again, this was a potentially expensive operation, decrease the
   // limits to get the regular clock call early
--- a/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/concurrentMark.hpp	Tue Oct 21 11:57:22 2014 +0200
@@ -519,15 +519,6 @@
   double cleanup_sleep_factor()             { return _cleanup_sleep_factor; }
   double cleanup_task_overhead()            { return _cleanup_task_overhead;}
 
-  bool use_parallel_marking_threads() const {
-    assert(parallel_marking_threads() <=
-           max_parallel_marking_threads(), "sanity");
-    assert((_parallel_workers == NULL && parallel_marking_threads() == 0) ||
-           parallel_marking_threads() > 0,
-           "parallel workers not set up correctly");
-    return _parallel_workers != NULL;
-  }
-
   HeapWord*               finger()          { return _finger;   }
   bool                    concurrent()      { return _concurrent; }
   uint                    active_tasks()    { return _active_tasks; }
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -1439,36 +1439,31 @@
       }
 
       // Rebuild remembered sets of all regions.
-      if (G1CollectedHeap::use_parallel_gc_threads()) {
-        uint n_workers =
-          AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
-                                                  workers()->active_workers(),
-                                                  Threads::number_of_non_daemon_threads());
-        assert(UseDynamicNumberOfGCThreads ||
-               n_workers == workers()->total_workers(),
-               "If not dynamic should be using all the  workers");
-        workers()->set_active_workers(n_workers);
-        // Set parallel threads in the heap (_n_par_threads) only
-        // before a parallel phase and always reset it to 0 after
-        // the phase so that the number of parallel threads does
-        // no get carried forward to a serial phase where there
-        // may be code that is "possibly_parallel".
-        set_par_threads(n_workers);
-
-        ParRebuildRSTask rebuild_rs_task(this);
-        assert(UseDynamicNumberOfGCThreads ||
-               workers()->active_workers() == workers()->total_workers(),
-               "Unless dynamic should use total workers");
-        // Use the most recent number of  active workers
-        assert(workers()->active_workers() > 0,
-               "Active workers not properly set");
-        set_par_threads(workers()->active_workers());
-        workers()->run_task(&rebuild_rs_task);
-        set_par_threads(0);
-      } else {
-        RebuildRSOutOfRegionClosure rebuild_rs(this);
-        heap_region_iterate(&rebuild_rs);
-      }
+      uint n_workers =
+        AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
+                                                workers()->active_workers(),
+                                                Threads::number_of_non_daemon_threads());
+      assert(UseDynamicNumberOfGCThreads ||
+             n_workers == workers()->total_workers(),
+             "If not dynamic should be using all the  workers");
+      workers()->set_active_workers(n_workers);
+      // Set parallel threads in the heap (_n_par_threads) only
+      // before a parallel phase and always reset it to 0 after
+      // the phase so that the number of parallel threads does
+      // no get carried forward to a serial phase where there
+      // may be code that is "possibly_parallel".
+      set_par_threads(n_workers);
+
+      ParRebuildRSTask rebuild_rs_task(this);
+      assert(UseDynamicNumberOfGCThreads ||
+             workers()->active_workers() == workers()->total_workers(),
+             "Unless dynamic should use total workers");
+      // Use the most recent number of  active workers
+      assert(workers()->active_workers() > 0,
+             "Active workers not properly set");
+      set_par_threads(workers()->active_workers());
+      workers()->run_task(&rebuild_rs_task);
+      set_par_threads(0);
 
       // Rebuild the strong code root lists for each region
       rebuild_strong_code_roots();
@@ -2681,27 +2676,25 @@
   // Then thread t will start at region floor ((t * n) / p)
 
   result = g1_policy()->collection_set();
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    uint cs_size = g1_policy()->cset_region_length();
-    uint active_workers = workers()->active_workers();
-    assert(UseDynamicNumberOfGCThreads ||
-             active_workers == workers()->total_workers(),
-             "Unless dynamic should use total workers");
-
-    uint end_ind   = (cs_size * worker_i) / active_workers;
-    uint start_ind = 0;
-
-    if (worker_i > 0 &&
-        _worker_cset_start_region_time_stamp[worker_i - 1] == gc_time_stamp) {
-      // Previous workers starting region is valid
-      // so let's iterate from there
-      start_ind = (cs_size * (worker_i - 1)) / active_workers;
-      result = _worker_cset_start_region[worker_i - 1];
-    }
-
-    for (uint i = start_ind; i < end_ind; i++) {
-      result = result->next_in_collection_set();
-    }
+  uint cs_size = g1_policy()->cset_region_length();
+  uint active_workers = workers()->active_workers();
+  assert(UseDynamicNumberOfGCThreads ||
+           active_workers == workers()->total_workers(),
+           "Unless dynamic should use total workers");
+
+  uint end_ind   = (cs_size * worker_i) / active_workers;
+  uint start_ind = 0;
+
+  if (worker_i > 0 &&
+      _worker_cset_start_region_time_stamp[worker_i - 1] == gc_time_stamp) {
+    // Previous workers starting region is valid
+    // so let's iterate from there
+    start_ind = (cs_size * (worker_i - 1)) / active_workers;
+    result = _worker_cset_start_region[worker_i - 1];
+  }
+
+  for (uint i = start_ind; i < end_ind; i++) {
+    result = result->next_in_collection_set();
   }
 
   // Note: the calculated starting heap region may be NULL
@@ -3376,9 +3369,7 @@
 }
 
 void G1CollectedHeap::print_gc_threads_on(outputStream* st) const {
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    workers()->print_worker_threads_on(st);
-  }
+  workers()->print_worker_threads_on(st);
   _cmThread->print_on(st);
   st->cr();
   _cm->print_worker_threads_on(st);
@@ -3389,9 +3380,7 @@
 }
 
 void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const {
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    workers()->threads_do(tc);
-  }
+  workers()->threads_do(tc);
   tc->do_thread(_cmThread);
   _cg1r->threads_do(tc);
   if (G1StringDedup::is_enabled()) {
@@ -3686,7 +3675,7 @@
   print_taskqueue_stats_hdr(st);
 
   TaskQueueStats totals;
-  const int n = workers() != NULL ? workers()->total_workers() : 1;
+  const int n = workers()->total_workers();
   for (int i = 0; i < n; ++i) {
     st->print("%3d ", i); task_queue(i)->stats.print(st); st->cr();
     totals += task_queue(i)->stats;
@@ -3697,7 +3686,7 @@
 }
 
 void G1CollectedHeap::reset_taskqueue_stats() {
-  const int n = workers() != NULL ? workers()->total_workers() : 1;
+  const int n = workers()->total_workers();
   for (int i = 0; i < n; ++i) {
     task_queue(i)->stats.reset();
   }
@@ -3795,8 +3784,7 @@
 
     TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
 
-    int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
-                                workers()->active_workers() : 1);
+    int active_workers = workers()->active_workers();
     double pause_start_sec = os::elapsedTime();
     g1_policy()->phase_times()->note_gc_start(active_workers);
     log_gc_header();
@@ -4790,12 +4778,10 @@
   int _symbols_processed;
   int _symbols_removed;
 
-  bool _do_in_parallel;
 public:
   G1StringSymbolTableUnlinkTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols) :
     AbstractGangTask("String/Symbol Unlinking"),
     _is_alive(is_alive),
-    _do_in_parallel(G1CollectedHeap::use_parallel_gc_threads()),
     _process_strings(process_strings), _strings_processed(0), _strings_removed(0),
     _process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0) {
 
@@ -4810,10 +4796,10 @@
   }
 
   ~G1StringSymbolTableUnlinkTask() {
-    guarantee(!_process_strings || !_do_in_parallel || StringTable::parallel_claimed_index() >= _initial_string_table_size,
+    guarantee(!_process_strings || StringTable::parallel_claimed_index() >= _initial_string_table_size,
               err_msg("claim value %d after unlink less than initial string table size %d",
                       StringTable::parallel_claimed_index(), _initial_string_table_size));
-    guarantee(!_process_symbols || !_do_in_parallel || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
+    guarantee(!_process_symbols || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
               err_msg("claim value %d after unlink less than initial symbol table size %d",
                       SymbolTable::parallel_claimed_index(), _initial_symbol_table_size));
 
@@ -4827,28 +4813,19 @@
   }
 
   void work(uint worker_id) {
-    if (_do_in_parallel) {
-      int strings_processed = 0;
-      int strings_removed = 0;
-      int symbols_processed = 0;
-      int symbols_removed = 0;
-      if (_process_strings) {
-        StringTable::possibly_parallel_unlink(_is_alive, &strings_processed, &strings_removed);
-        Atomic::add(strings_processed, &_strings_processed);
-        Atomic::add(strings_removed, &_strings_removed);
-      }
-      if (_process_symbols) {
-        SymbolTable::possibly_parallel_unlink(&symbols_processed, &symbols_removed);
-        Atomic::add(symbols_processed, &_symbols_processed);
-        Atomic::add(symbols_removed, &_symbols_removed);
-      }
-    } else {
-      if (_process_strings) {
-        StringTable::unlink(_is_alive, &_strings_processed, &_strings_removed);
-      }
-      if (_process_symbols) {
-        SymbolTable::unlink(&_symbols_processed, &_symbols_removed);
-      }
+    int strings_processed = 0;
+    int strings_removed = 0;
+    int symbols_processed = 0;
+    int symbols_removed = 0;
+    if (_process_strings) {
+      StringTable::possibly_parallel_unlink(_is_alive, &strings_processed, &strings_removed);
+      Atomic::add(strings_processed, &_strings_processed);
+      Atomic::add(strings_removed, &_strings_removed);
+    }
+    if (_process_symbols) {
+      SymbolTable::possibly_parallel_unlink(&symbols_processed, &symbols_removed);
+      Atomic::add(symbols_processed, &_symbols_processed);
+      Atomic::add(symbols_removed, &_symbols_removed);
     }
   }
 
@@ -5149,33 +5126,23 @@
                                         bool process_strings,
                                         bool process_symbols,
                                         bool class_unloading_occurred) {
-  uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
-                    workers()->active_workers() : 1);
+  uint n_workers = workers()->active_workers();
 
   G1ParallelCleaningTask g1_unlink_task(is_alive, process_strings, process_symbols,
                                         n_workers, class_unloading_occurred);
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
+  set_par_threads(n_workers);
+  workers()->run_task(&g1_unlink_task);
+  set_par_threads(0);
+}
+
+void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive,
+                                                     bool process_strings, bool process_symbols) {
+  {
+    uint n_workers = _g1h->workers()->active_workers();
+    G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols);
     set_par_threads(n_workers);
     workers()->run_task(&g1_unlink_task);
     set_par_threads(0);
-  } else {
-    g1_unlink_task.work(0);
-  }
-}
-
-void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive,
-                                                     bool process_strings, bool process_symbols) {
-  {
-    uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
-                     _g1h->workers()->active_workers() : 1);
-    G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols);
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      set_par_threads(n_workers);
-      workers()->run_task(&g1_unlink_task);
-      set_par_threads(0);
-    } else {
-      g1_unlink_task.work(0);
-    }
   }
 
   if (G1StringDedup::is_enabled()) {
@@ -5193,11 +5160,7 @@
     double start_time = os::elapsedTime();
 
     RedirtyLoggedCardTableEntryClosure cl;
-    if (G1CollectedHeap::heap()->use_parallel_gc_threads()) {
-      _queue->par_apply_closure_to_all_completed_buffers(&cl);
-    } else {
-      _queue->apply_closure_to_all_completed_buffers(&cl);
-    }
+    _queue->par_apply_closure_to_all_completed_buffers(&cl);
 
     G1GCPhaseTimes* timer = G1CollectedHeap::heap()->g1_policy()->phase_times();
     timer->record_redirty_logged_cards_time_ms(worker_id, (os::elapsedTime() - start_time) * 1000.0);
@@ -5208,18 +5171,13 @@
 void G1CollectedHeap::redirty_logged_cards() {
   double redirty_logged_cards_start = os::elapsedTime();
 
-  uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
-                   _g1h->workers()->active_workers() : 1);
+  uint n_workers = _g1h->workers()->active_workers();
 
   G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set());
   dirty_card_queue_set().reset_for_par_iteration();
-  if (use_parallel_gc_threads()) {
-    set_par_threads(n_workers);
-    workers()->run_task(&redirty_task);
-    set_par_threads(0);
-  } else {
-    redirty_task.work(0);
-  }
+  set_par_threads(n_workers);
+  workers()->run_task(&redirty_task);
+  set_par_threads(0);
 
   DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set();
   dcq.merge_bufferlists(&dirty_card_queue_set());
@@ -5609,20 +5567,14 @@
   // referents points to another object which is also referenced by an
   // object discovered by the STW ref processor.
 
-  assert(!G1CollectedHeap::use_parallel_gc_threads() ||
-           no_of_gc_workers == workers()->active_workers(),
-           "Need to reset active GC workers");
+  assert(no_of_gc_workers == workers()->active_workers(), "Need to reset active GC workers");
 
   set_par_threads(no_of_gc_workers);
   G1ParPreserveCMReferentsTask keep_cm_referents(this,
                                                  no_of_gc_workers,
                                                  _task_queues);
 
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    workers()->run_task(&keep_cm_referents);
-  } else {
-    keep_cm_referents.work(0);
-  }
+  workers()->run_task(&keep_cm_referents);
 
   set_par_threads(0);
 
@@ -5749,21 +5701,15 @@
   hot_card_cache->set_use_cache(false);
 
   uint n_workers;
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    n_workers =
-      AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
-                                     workers()->active_workers(),
-                                     Threads::number_of_non_daemon_threads());
-    assert(UseDynamicNumberOfGCThreads ||
-           n_workers == workers()->total_workers(),
-           "If not dynamic should be using all the  workers");
-    workers()->set_active_workers(n_workers);
-    set_par_threads(n_workers);
-  } else {
-    assert(n_par_threads() == 0,
-           "Should be the original non-parallel value");
-    n_workers = 1;
-  }
+  n_workers =
+    AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(),
+                                   workers()->active_workers(),
+                                   Threads::number_of_non_daemon_threads());
+  assert(UseDynamicNumberOfGCThreads ||
+         n_workers == workers()->total_workers(),
+         "If not dynamic should be using all the  workers");
+  workers()->set_active_workers(n_workers);
+  set_par_threads(n_workers);
 
   G1ParTask g1_par_task(this, _task_queues);
 
@@ -5782,18 +5728,13 @@
       ClassLoaderDataGraph::clear_claimed_marks();
     }
 
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      // The individual threads will set their evac-failure closures.
-      if (PrintTerminationStats) G1ParScanThreadState::print_termination_stats_hdr();
-      // These tasks use ShareHeap::_process_strong_tasks
-      assert(UseDynamicNumberOfGCThreads ||
-             workers()->active_workers() == workers()->total_workers(),
-             "If not dynamic should be using all the  workers");
-      workers()->run_task(&g1_par_task);
-    } else {
-      g1_par_task.set_for_termination(n_workers);
-      g1_par_task.work(0);
-    }
+     // The individual threads will set their evac-failure closures.
+     if (PrintTerminationStats) G1ParScanThreadState::print_termination_stats_hdr();
+     // These tasks use ShareHeap::_process_strong_tasks
+     assert(UseDynamicNumberOfGCThreads ||
+            workers()->active_workers() == workers()->total_workers(),
+            "If not dynamic should be using all the  workers");
+    workers()->run_task(&g1_par_task);
     end_par_time_sec = os::elapsedTime();
 
     // Closing the inner scope will execute the destructor
@@ -6099,22 +6040,9 @@
     // Iterate over the dirty cards region list.
     G1ParCleanupCTTask cleanup_task(ct_bs, this);
 
-    if (G1CollectedHeap::use_parallel_gc_threads()) {
-      set_par_threads();
-      workers()->run_task(&cleanup_task);
-      set_par_threads(0);
-    } else {
-      while (_dirty_cards_region_list) {
-        HeapRegion* r = _dirty_cards_region_list;
-        cleanup_task.clear_cards(r);
-        _dirty_cards_region_list = r->get_next_dirty_cards_region();
-        if (_dirty_cards_region_list == r) {
-          // The last region.
-          _dirty_cards_region_list = NULL;
-        }
-        r->set_next_dirty_cards_region(NULL);
-      }
-    }
+    set_par_threads();
+    workers()->run_task(&cleanup_task);
+    set_par_threads(0);
 #ifndef PRODUCT
     if (G1VerifyCTCleanup || VerifyAfterGC) {
       G1VerifyCardTableCleanup cleanup_verifier(this, ct_bs);
@@ -6654,7 +6582,6 @@
 void G1CollectedHeap::set_par_threads() {
   // Don't change the number of workers.  Use the value previously set
   // in the workgroup.
-  assert(G1CollectedHeap::use_parallel_gc_threads(), "shouldn't be here otherwise");
   uint n_workers = workers()->active_workers();
   assert(UseDynamicNumberOfGCThreads ||
            n_workers == workers()->total_workers(),
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -84,8 +84,7 @@
 };
 
 G1CollectorPolicy::G1CollectorPolicy() :
-  _parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads()
-                        ? ParallelGCThreads : 1),
+  _parallel_gc_threads(ParallelGCThreads),
 
   _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
   _stop_world_start(0.0),
@@ -1544,32 +1543,6 @@
   }
 }
 
-class KnownGarbageClosure: public HeapRegionClosure {
-  G1CollectedHeap* _g1h;
-  CollectionSetChooser* _hrSorted;
-
-public:
-  KnownGarbageClosure(CollectionSetChooser* hrSorted) :
-    _g1h(G1CollectedHeap::heap()), _hrSorted(hrSorted) { }
-
-  bool doHeapRegion(HeapRegion* r) {
-    // We only include humongous regions in collection
-    // sets when concurrent mark shows that their contained object is
-    // unreachable.
-
-    // Do we have any marking information for this region?
-    if (r->is_marked()) {
-      // We will skip any region that's currently used as an old GC
-      // alloc region (we should not consider those for collection
-      // before we fill them up).
-      if (_hrSorted->should_add(r) && !_g1h->is_old_gc_alloc_region(r)) {
-        _hrSorted->add_region(r);
-      }
-    }
-    return false;
-  }
-};
-
 class ParKnownGarbageHRClosure: public HeapRegionClosure {
   G1CollectedHeap* _g1h;
   CSetChooserParUpdater _cset_updater;
@@ -1617,34 +1590,29 @@
   _collectionSetChooser->clear();
 
   uint region_num = _g1->num_regions();
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    const uint OverpartitionFactor = 4;
-    uint WorkUnit;
-    // The use of MinChunkSize = 8 in the original code
-    // causes some assertion failures when the total number of
-    // region is less than 8.  The code here tries to fix that.
-    // Should the original code also be fixed?
-    if (no_of_gc_threads > 0) {
-      const uint MinWorkUnit = MAX2(region_num / no_of_gc_threads, 1U);
-      WorkUnit = MAX2(region_num / (no_of_gc_threads * OverpartitionFactor),
-                      MinWorkUnit);
-    } else {
-      assert(no_of_gc_threads > 0,
-        "The active gc workers should be greater than 0");
-      // In a product build do something reasonable to avoid a crash.
-      const uint MinWorkUnit = MAX2(region_num / (uint) ParallelGCThreads, 1U);
-      WorkUnit =
-        MAX2(region_num / (uint) (ParallelGCThreads * OverpartitionFactor),
-             MinWorkUnit);
-    }
-    _collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(),
-                                                           WorkUnit);
-    ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, WorkUnit, (uint) no_of_gc_threads);
-    _g1->workers()->run_task(&parKnownGarbageTask);
+  const uint OverpartitionFactor = 4;
+  uint WorkUnit;
+  // The use of MinChunkSize = 8 in the original code
+  // causes some assertion failures when the total number of
+  // region is less than 8.  The code here tries to fix that.
+  // Should the original code also be fixed?
+  if (no_of_gc_threads > 0) {
+    const uint MinWorkUnit = MAX2(region_num / no_of_gc_threads, 1U);
+    WorkUnit = MAX2(region_num / (no_of_gc_threads * OverpartitionFactor),
+                    MinWorkUnit);
   } else {
-    KnownGarbageClosure knownGarbagecl(_collectionSetChooser);
-    _g1->heap_region_iterate(&knownGarbagecl);
+    assert(no_of_gc_threads > 0,
+      "The active gc workers should be greater than 0");
+    // In a product build do something reasonable to avoid a crash.
+    const uint MinWorkUnit = MAX2(region_num / (uint) ParallelGCThreads, 1U);
+    WorkUnit =
+      MAX2(region_num / (uint) (ParallelGCThreads * OverpartitionFactor),
+           MinWorkUnit);
   }
+  _collectionSetChooser->prepare_for_par_region_addition(_g1->num_regions(),
+                                                         WorkUnit);
+  ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser, WorkUnit, (uint) no_of_gc_threads);
+  _g1->workers()->run_task(&parKnownGarbageTask);
 
   _collectionSetChooser->sort_regions();
 
--- a/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -292,36 +292,25 @@
   if (_root_region_scan_wait_time_ms > 0.0) {
     print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
   }
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
-    _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
-    _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
-    if (_last_satb_filtering_times_ms.sum() > 0.0) {
-      _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
-    }
-    _last_update_rs_times_ms.print(2, "Update RS (ms)");
-      _last_update_rs_processed_buffers.print(3, "Processed Buffers");
-    _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
-    _last_strong_code_root_scan_times_ms.print(2, "Code Root Scanning (ms)");
-    _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
-    _last_termination_times_ms.print(2, "Termination (ms)");
-    if (G1Log::finest()) {
-      _last_termination_attempts.print(3, "Termination Attempts");
-    }
-    _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
-    _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
-    _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
-  } else {
-    _last_ext_root_scan_times_ms.print(1, "Ext Root Scanning (ms)");
-    if (_last_satb_filtering_times_ms.sum() > 0.0) {
-      _last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
-    }
-    _last_update_rs_times_ms.print(1, "Update RS (ms)");
-      _last_update_rs_processed_buffers.print(2, "Processed Buffers");
-    _last_scan_rs_times_ms.print(1, "Scan RS (ms)");
-    _last_strong_code_root_scan_times_ms.print(1, "Code Root Scanning (ms)");
-    _last_obj_copy_times_ms.print(1, "Object Copy (ms)");
+  print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
+  _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
+  _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
+  if (_last_satb_filtering_times_ms.sum() > 0.0) {
+    _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
   }
+  _last_update_rs_times_ms.print(2, "Update RS (ms)");
+    _last_update_rs_processed_buffers.print(3, "Processed Buffers");
+  _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
+  _last_strong_code_root_scan_times_ms.print(2, "Code Root Scanning (ms)");
+  _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
+  _last_termination_times_ms.print(2, "Termination (ms)");
+  if (G1Log::finest()) {
+    _last_termination_attempts.print(3, "Termination Attempts");
+  }
+  _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
+  _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
+  _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
+
   print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
   print_stats(1, "Code Root Purge", _cur_strong_code_root_purge_time_ms);
   if (G1StringDedup::is_enabled()) {
--- a/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1HotCardCache.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -43,7 +43,7 @@
     _hot_cache_idx = 0;
 
     // For refining the cards in the hot cache in parallel
-    _hot_cache_par_chunk_size = (ParallelGCThreads > 0 ? ClaimChunkSize : _hot_cache_size);
+    _hot_cache_par_chunk_size = ClaimChunkSize;
     _hot_cache_par_claimed_idx = 0;
 
     _card_counts.initialize(card_counts_storage);
@@ -119,7 +119,7 @@
             // RSet updating while within an evacuation pause.
             // In this case worker_i should be the id of a GC worker thread
             assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
-            assert(worker_i < (ParallelGCThreads == 0 ? 1 : ParallelGCThreads),
+            assert(worker_i < ParallelGCThreads,
                    err_msg("incorrect worker id: %u", worker_i));
 
             into_cset_dcq->enqueue(card_ptr);
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -80,7 +80,6 @@
     _prev_period_summary()
 {
   _seq_task = new SubTasksDone(NumSeqTasks);
-  guarantee(n_workers() > 0, "There should be some workers");
   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC);
   for (uint i = 0; i < n_workers(); i++) {
     _cset_rs_update_cl[i] = NULL;
@@ -282,7 +281,7 @@
     // is during RSet updating within an evacuation pause.
     // In this case worker_i should be the id of a GC worker thread.
     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
-    assert(worker_i < (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
+    assert(worker_i < ParallelGCThreads, "should be a GC worker");
 
     if (_g1rs->refine_card(card_ptr, worker_i, true)) {
       // 'card_ptr' contains references that point into the collection
@@ -343,8 +342,6 @@
   // DirtyCardQueueSet that is used to manage RSet updates
   DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
 
-  assert((ParallelGCThreads > 0) || worker_i == 0, "invariant");
-
   updateRS(&into_cset_dcq, worker_i);
   scanRS(oc, code_root_cl, worker_i);
 
@@ -420,12 +417,7 @@
   }
 };
 
-void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) {
-  ScrubRSClosure scrub_cl(region_bm, card_bm);
-  _g1->heap_region_iterate(&scrub_cl);
-}
-
-void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
+void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
   ScrubRSClosure scrub_cl(region_bm, card_bm);
   _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
 }
--- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp	Tue Oct 21 11:57:22 2014 +0200
@@ -124,14 +124,10 @@
   // Requires "region_bm" and "card_bm" to be bitmaps with 1 bit per region
   // or card, respectively, such that a region or card with a corresponding
   // 0 bit contains no part of any live object.  Eliminates any remembered
-  // set entries that correspond to dead heap ranges.
-  void scrub(BitMap* region_bm, BitMap* card_bm);
-
-  // Like the above, but assumes is called in parallel: "worker_num" is the
-  // parallel thread id of the current thread, and "hrclaimer" is the shared
-  // HeapRegionClaimer that should be used to claim heap regions.
-  void scrub_par(BitMap* region_bm, BitMap* card_bm,
-                 uint worker_num, HeapRegionClaimer* hrclaimer);
+  // set entries that correspond to dead heap ranges. "worker_num" is the
+  // parallel thread id of the current thread, and "hrclaimer" is the
+  // HeapRegionClaimer that should be used.
+  void scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer* hrclaimer);
 
   // Refine the card corresponding to "card_ptr".
   // If check_for_refs_into_cset is true, a true result is returned
--- a/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Tue Oct 21 11:57:22 2014 +0200
@@ -31,11 +31,7 @@
 #include "oops/oop.inline.hpp"
 
 inline uint G1RemSet::n_workers() {
-  if (_g1->workers() != NULL) {
-    return _g1->workers()->total_workers();
-  } else {
-    return 1;
-  }
+  return _g1->workers()->total_workers();
 }
 
 template <class T>
--- a/src/share/vm/gc_implementation/g1/g1StringDedup.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/g1StringDedup.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -154,14 +154,10 @@
   double fixup_start = os::elapsedTime();
 
   G1StringDedupUnlinkOrOopsDoTask task(is_alive, keep_alive, allow_resize_and_rehash);
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    G1CollectedHeap* g1h = G1CollectedHeap::heap();
-    g1h->set_par_threads();
-    g1h->workers()->run_task(&task);
-    g1h->set_par_threads(0);
-  } else {
-    task.work(0);
-  }
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  g1h->set_par_threads();
+  g1h->workers()->run_task(&task);
+  g1h->set_par_threads(0);
 
   double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0;
   g1p->phase_times()->record_string_dedup_fixup_time(fixup_time_ms);
--- a/src/share/vm/gc_implementation/g1/satbQueue.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/satbQueue.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -202,7 +202,7 @@
 #endif // _MSC_VER
 
 SATBMarkQueueSet::SATBMarkQueueSet() :
-  PtrQueueSet(), _closure(NULL), _par_closures(NULL),
+  PtrQueueSet(), _closures(NULL),
   _shared_satb_queue(this, true /*perm*/) { }
 
 void SATBMarkQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
@@ -210,9 +210,7 @@
                                   Mutex* lock) {
   PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
   _shared_satb_queue.set_lock(lock);
-  if (ParallelGCThreads > 0) {
-    _par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC);
-  }
+  _closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC);
 }
 
 void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
@@ -276,17 +274,13 @@
   shared_satb_queue()->filter();
 }
 
-void SATBMarkQueueSet::set_closure(ObjectClosure* closure) {
-  _closure = closure;
+void SATBMarkQueueSet::set_closure(uint worker, ObjectClosure* closure) {
+  assert(_closures != NULL, "Precondition");
+  assert(worker < ParallelGCThreads, "Worker index must be in range [0...ParallelGCThreads)");
+  _closures[worker] = closure;
 }
 
-void SATBMarkQueueSet::set_par_closure(int i, ObjectClosure* par_closure) {
-  assert(ParallelGCThreads > 0 && _par_closures != NULL, "Precondition");
-  _par_closures[i] = par_closure;
-}
-
-bool SATBMarkQueueSet::apply_closure_to_completed_buffer_work(bool par,
-                                                              uint worker) {
+bool SATBMarkQueueSet::apply_closure_to_completed_buffer(uint worker) {
   BufferNode* nd = NULL;
   {
     MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
@@ -298,7 +292,7 @@
       if (_n_completed_buffers == 0) _process_completed = false;
     }
   }
-  ObjectClosure* cl = (par ? _par_closures[worker] : _closure);
+  ObjectClosure* cl = _closures[worker];
   if (nd != NULL) {
     void **buf = BufferNode::make_buffer_from_node(nd);
     ObjPtrQueue::apply_closure_to_buffer(cl, buf, 0, _sz);
--- a/src/share/vm/gc_implementation/g1/satbQueue.hpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/satbQueue.hpp	Tue Oct 21 11:57:22 2014 +0200
@@ -78,16 +78,10 @@
 };
 
 class SATBMarkQueueSet: public PtrQueueSet {
-  ObjectClosure* _closure;
-  ObjectClosure** _par_closures;  // One per ParGCThread.
+  ObjectClosure** _closures;  // One per ParGCThread.
 
   ObjPtrQueue _shared_satb_queue;
 
-  // Utility function to support sequential and parallel versions.  If
-  // "par" is true, then "worker" is the par thread id; if "false", worker
-  // is ignored.
-  bool apply_closure_to_completed_buffer_work(bool par, uint worker);
-
 #ifdef ASSERT
   void dump_active_states(bool expected_active);
   void verify_active_states(bool expected_active);
@@ -111,26 +105,16 @@
   // Filter all the currently-active SATB buffers.
   void filter_thread_buffers();
 
-  // Register "blk" as "the closure" for all queues.  Only one such closure
-  // is allowed.  The "apply_closure_to_completed_buffer" method will apply
-  // this closure to a completed buffer, and "iterate_closure_all_threads"
+  // Register closure for the given worker thread. The "apply_closure_to_completed_buffer"
+  // method will apply this closure to a completed buffer, and "iterate_closure_all_threads"
   // applies it to partially-filled buffers (the latter should only be done
   // with the world stopped).
-  void set_closure(ObjectClosure* closure);
-  // Set the parallel closures: pointer is an array of pointers to
-  // closures, one for each parallel GC thread.
-  void set_par_closure(int i, ObjectClosure* closure);
+  void set_closure(uint worker, ObjectClosure* closure);
 
   // If there exists some completed buffer, pop it, then apply the
   // registered closure to all its elements, and return true.  If no
   // completed buffers exist, return false.
-  bool apply_closure_to_completed_buffer() {
-    return apply_closure_to_completed_buffer_work(false, 0);
-  }
-  // Parallel version of the above.
-  bool par_apply_closure_to_completed_buffer(uint worker) {
-    return apply_closure_to_completed_buffer_work(true, worker);
-  }
+  bool apply_closure_to_completed_buffer(uint worker);
 
   // Apply the given closure on enqueued and currently-active buffers
   // respectively. Both methods are read-only, i.e., they do not
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -479,7 +479,7 @@
     _next_gen.par_oop_since_save_marks_iterate_done(i);
   }
 
-  if (UseConcMarkSweepGC && ParallelGCThreads > 0) {
+  if (UseConcMarkSweepGC) {
     // We need to call this even when ResizeOldPLAB is disabled
     // so as to avoid breaking some asserts. While we may be able
     // to avoid this by reorganizing the code a bit, I am loathe
--- a/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -47,11 +47,6 @@
   // Do basic sizing work
   GenCollectorPolicy::initialize_flags();
 
-  assert(UseSerialGC ||
-          !FLAG_IS_DEFAULT(ParallelGCThreads) ||
-          (ParallelGCThreads > 0),
-         "ParallelGCThreads should be set before flag initialization");
-
   // The survivor ratio's are calculated "raw", unlike the
   // default gc, which adds 2 to the ratio value. We need to
   // make sure the values are valid before using them.
--- a/src/share/vm/memory/freeBlockDictionary.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/memory/freeBlockDictionary.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -43,12 +43,10 @@
 
 template <class Chunk> void FreeBlockDictionary<Chunk>::verify_par_locked() const {
 #ifdef ASSERT
-  if (ParallelGCThreads > 0) {
-    Thread* my_thread = Thread::current();
-    if (my_thread->is_GC_task_thread()) {
-      assert(par_lock() != NULL, "Should be using locking?");
-      assert_lock_strong(par_lock());
-    }
+  Thread* my_thread = Thread::current();
+  if (my_thread->is_GC_task_thread()) {
+    assert(par_lock() != NULL, "Should be using locking?");
+    assert_lock_strong(par_lock());
   }
 #endif // ASSERT
 }
--- a/src/share/vm/memory/freeList.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/memory/freeList.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -287,11 +287,14 @@
   return false;
 }
 
-#ifndef PRODUCT
+#ifdef ASSERT
 template <class Chunk>
 void FreeList<Chunk>::assert_proper_lock_protection_work() const {
-  assert(protecting_lock() != NULL, "Don't call this directly");
-  assert(ParallelGCThreads > 0, "Don't call this directly");
+  // Nothing to do if the list has no assigned protecting lock
+  if (protecting_lock() == NULL) {
+    return;
+  }
+
   Thread* thr = Thread::current();
   if (thr->is_VM_thread() || thr->is_ConcurrentGC_thread()) {
     // assert that we are holding the freelist lock
--- a/src/share/vm/memory/freeList.hpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/memory/freeList.hpp	Tue Oct 21 11:57:22 2014 +0200
@@ -56,15 +56,12 @@
 
 #ifdef ASSERT
   Mutex*        _protecting_lock;
+  void assert_proper_lock_protection_work() const;
 #endif
 
   // Asserts false if the protecting lock (if any) is not held.
-  void assert_proper_lock_protection_work() const PRODUCT_RETURN;
   void assert_proper_lock_protection() const {
-#ifdef ASSERT
-    if (_protecting_lock != NULL)
-      assert_proper_lock_protection_work();
-#endif
+    DEBUG_ONLY(assert_proper_lock_protection_work());
   }
 
   void increment_count()    {
--- a/src/share/vm/memory/sharedHeap.cpp	Mon Oct 20 10:18:17 2014 +0200
+++ b/src/share/vm/memory/sharedHeap.cpp	Tue Oct 21 11:57:22 2014 +0200
@@ -68,11 +68,9 @@
     vm_exit_during_initialization("Failed necessary allocation.");
   }
   _sh = this;  // ch is static, should be set only once.
-  if ((UseParNewGC ||
-      (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled ||
-                              CMSParallelRemarkEnabled)) ||
-       UseG1GC) &&
-      ParallelGCThreads > 0) {
+  if (UseParNewGC ||
+      UseG1GC ||
+      (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled || CMSParallelRemarkEnabled) && use_parallel_gc_threads())) {
     _workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
                             /* are_GC_task_threads */true,
                             /* are_ConcurrentGC_threads */false);