index

src/share/vm/gc_implementation/g1/concurrentMark.cpp

Print this page
rev 7209 : 6979279
rev 7210 : imported patch rev1

@@ -609,18 +609,10 @@
     warning("Can't have more ConcGCThreads (" UINTX_FORMAT ") "
             "than ParallelGCThreads (" UINTX_FORMAT ").",
             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;
-  } 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;

@@ -669,19 +661,17 @@
     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();
     }
-  }
 
   if (FLAG_IS_DEFAULT(MarkStackSize)) {
     uintx mark_stack_size =
       MIN2(MarkStackSizeMax,
           MAX2(MarkStackSize, (uintx) (parallel_marking_threads() * TASKQUEUE_SIZE)));

@@ -1164,11 +1154,10 @@
 };
 
 // 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();

@@ -1182,15 +1171,10 @@
       // 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;
-  }
-  // 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;
 }
 
 void ConcurrentMark::scanRootRegion(HeapRegion* hr, uint worker_id) {
   // Currently, only survivors can be root regions.
   assert(hr->next_top_at_mark_start() == hr->bottom(), "invariant");

@@ -1241,16 +1225,12 @@
     assert(parallel_marking_threads() <= max_parallel_marking_threads(),
            "Maximum number of marking threads exceeded");
     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->set_active_workers(active_workers);
       _parallel_workers->run_task(&task);
-    } else {
-      task.work(0);
-    }
 
     // It's possible that has_aborted() is true here without actually
     // aborting the survivor scan earlier. This is OK as it's
     // mainly used for sanity checking.
     root_regions()->scan_finished();

@@ -1277,19 +1257,15 @@
 
   // Parallel task terminator is set in "set_concurrency_and_phase()"
   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);
+  _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);
-  } else {
-    markingTask.work(0);
-  }
   print_stats();
 }
 
 // Helper class to get rid of some boilerplate code.
 class G1CMTraceTime : public GCTraceTime {

@@ -1712,15 +1688,11 @@
                                             _actual_region_bm, _actual_card_bm,
                                             _expected_region_bm,
                                             _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);
-    }
 
     Atomic::add(verify_cl.failures(), &_failures);
   }
 
   int failures() const { return _failures; }

@@ -1819,15 +1791,11 @@
 
     FinalCountDataUpdateClosure final_update_cl(_g1h,
                                                 _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);
-    }
   }
 };
 
 class G1ParNoteEndTask;
 

@@ -1920,15 +1888,11 @@
     double start = os::elapsedTime();
     FreeRegionList local_cleanup_list("Local Cleanup List");
     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);
-    }
     assert(g1_note_end.complete(), "Shouldn't have yielded!");
 
     // Now update the lists
     _g1h->remove_from_old_sets(g1_note_end.old_regions_removed(), g1_note_end.humongous_regions_removed());
     {

@@ -1975,15 +1939,11 @@
   G1ParScrubRemSetTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm, uint n_workers) :
       AbstractGangTask("G1 ScrubRS"), _g1rs(g1h->g1_rem_set()), _region_bm(region_bm), _card_bm(card_bm), _hrclaimer(n_workers) {
   }
 
   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);
   }
 
 };
 
 void ConcurrentMark::cleanup() {

@@ -2018,22 +1978,17 @@
   uint n_workers;
 
   // 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);
-  }
 
   if (VerifyDuringGC) {
     // Verify that the counting data accumulated during marking matches
     // that calculated by walking the marking bitmap.
 

@@ -2045,18 +2000,14 @@
                                                  &_region_bm,
                                                  &_card_bm,
                                                  &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);
-    }
 
     guarantee(g1_par_verify_task.failures() == 0, "Unexpected accounting failures");
   }
 
   size_t start_used_bytes = g1h->used();

@@ -2076,17 +2027,13 @@
 
   g1h->reset_gc_time_stamp();
 
   // 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->check_gc_time_stamps();
 
   if (!cleanup_list_is_empty()) {
     // The cleanup list is not empty, so we'll have to process it
     // concurrently. Notify anyone else that might be wanting free

@@ -2097,17 +2044,13 @@
   // call below, since it affects the metric by which we sort the heap
   // regions.
   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);
-    }
 
     double rs_scrub_end = os::elapsedTime();
     double this_rs_scrub_time = (rs_scrub_end - rs_scrub_start);
     _total_rs_scrub_time += this_rs_scrub_time;
   }

@@ -2500,11 +2443,11 @@
 
     // We need at least one active thread. If reference processing
     // 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);
 
     // Parallel processing task executor.
     G1CMRefProcTaskExecutor par_task_executor(g1h, this,

@@ -2609,20 +2552,19 @@
 class G1RemarkThreadsClosure : public ThreadClosure {
   CMObjectClosure _cm_obj;
   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
         // however the liveness of oops reachable from nmethods have very complex lifecycles:
         // * Alive if on the stack of an executing method

@@ -2632,21 +2574,20 @@
         jt->nmethods_do(&_code_cl);
 
         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);
       }
     }
   }
 };
 
 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
     // only proceed if we're supposed to be active.
     if (worker_id < _cm->active_tasks()) {

@@ -2654,27 +2595,27 @@
       task->record_start_time();
       {
         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.
       task->record_end_time();
     }
   }
 
-  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);
   }
 };
 
 void ConcurrentMark::checkpointRootsFinalWork() {

@@ -2684,11 +2625,10 @@
 
   G1CMTraceTime trace("Finalize Marking", G1Log::finer());
 
   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");

@@ -2699,32 +2639,18 @@
     // 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 */);
+  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);
-  } 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);
-  }
   SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
   guarantee(has_overflown() ||
             satb_mq_set.completed_buffers_num() == 0,
             err_msg("Invariant: has_overflown = %s, num buffers = %d",
                     BOOL_TO_STR(has_overflown()),

@@ -3266,34 +3192,24 @@
   }
 
   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);
-    }
   }
 };
 
 
 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->allocation_context_stats().update_at_remark();
 }
 
 // Clear the per-worker arrays used to store the per-region counting data
 void ConcurrentMark::clear_all_count_data() {

@@ -3417,13 +3333,11 @@
                 cmThread()->vtime_accum(),
                 cmThread()->vtime_mark_accum());
 }
 
 void ConcurrentMark::print_worker_threads_on(outputStream* st) const {
-  if (use_parallel_marking_threads()) {
     _parallel_workers->print_worker_threads_on(st);
-  }
 }
 
 void ConcurrentMark::print_on_error(outputStream* st) const {
   st->print_cr("Marking Bits (Prev, Next): (CMBitMap*) " PTR_FORMAT ", (CMBitMap*) " PTR_FORMAT,
       p2i(_prevMarkBitMap), p2i(_nextMarkBitMap));

@@ -3940,49 +3854,30 @@
   // very counter productive if it did that. :-)
   _draining_satb_buffers = true;
 
   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();
-    }
-  } else {
     while (!has_aborted() &&
-           satb_mq_set.apply_closure_to_completed_buffer()) {
+         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);
       }
       statsOnly( ++_satb_buffers_processed );
       regular_clock_call();
     }
-  }
 
   _draining_satb_buffers = false;
 
   assert(has_aborted() ||
          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
   decrease_limits();
 }
index