changeset 9417:a6499084ccd4

Merge
author coleenp
date Tue, 06 Oct 2015 18:51:47 +0000
parents f10efc097bae 17cfe2c6dc00
children 00e5743fd189
files
diffstat 3 files changed, 135 insertions(+), 362 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc/parallel/gcTaskManager.cpp	Tue Oct 06 14:27:39 2015 -0400
+++ b/src/share/vm/gc/parallel/gcTaskManager.cpp	Tue Oct 06 18:51:47 2015 +0000
@@ -26,6 +26,7 @@
 #include "gc/parallel/gcTaskManager.hpp"
 #include "gc/parallel/gcTaskThread.hpp"
 #include "gc/shared/adaptiveSizePolicy.hpp"
+#include "gc/shared/gcId.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/mutex.hpp"
@@ -48,8 +49,8 @@
   case ordinary_task:
     result = "ordinary task";
     break;
-  case barrier_task:
-    result = "barrier task";
+  case wait_for_barrier_task:
+    result = "wait for barrier task";
     break;
   case noop_task:
     result = "noop task";
@@ -61,33 +62,24 @@
   return result;
 };
 
-GCTask::GCTask() :
-  _kind(Kind::ordinary_task),
-  _affinity(GCTaskManager::sentinel_worker()){
-  initialize();
+GCTask::GCTask() {
+  initialize(Kind::ordinary_task, GCId::current());
 }
 
-GCTask::GCTask(Kind::kind kind) :
-  _kind(kind),
-  _affinity(GCTaskManager::sentinel_worker()) {
-  initialize();
+GCTask::GCTask(Kind::kind kind) {
+  initialize(kind, GCId::current());
 }
 
-GCTask::GCTask(uint affinity) :
-  _kind(Kind::ordinary_task),
-  _affinity(affinity) {
-  initialize();
+GCTask::GCTask(Kind::kind kind, uint gc_id) {
+  initialize(kind, gc_id);
 }
 
-GCTask::GCTask(Kind::kind kind, uint affinity) :
-  _kind(kind),
-  _affinity(affinity) {
-  initialize();
-}
-
-void GCTask::initialize() {
+void GCTask::initialize(Kind::kind kind, uint gc_id) {
+  _kind = kind;
+  _affinity = GCTaskManager::sentinel_worker();
   _older = NULL;
   _newer = NULL;
+  _gc_id = gc_id;
 }
 
 void GCTask::destruct() {
@@ -378,16 +370,7 @@
 GCTaskManager::GCTaskManager(uint workers) :
   _workers(workers),
   _active_workers(0),
-  _idle_workers(0),
-  _ndc(NULL) {
-  initialize();
-}
-
-GCTaskManager::GCTaskManager(uint workers, NotifyDoneClosure* ndc) :
-  _workers(workers),
-  _active_workers(0),
-  _idle_workers(0),
-  _ndc(ndc) {
+  _idle_workers(0) {
   initialize();
 }
 
@@ -404,7 +387,6 @@
   GCTaskQueue* unsynchronized_queue = GCTaskQueue::create_on_c_heap();
   _queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock());
   _noop_task = NoopGCTask::create_on_c_heap();
-  _idle_inactive_task = WaitForBarrierGCTask::create_on_c_heap();
   _resource_flag = NEW_C_HEAP_ARRAY(bool, workers(), mtGC);
   {
     // Set up worker threads.
@@ -437,7 +419,6 @@
   }
   reset_delivered_tasks();
   reset_completed_tasks();
-  reset_noop_tasks();
   reset_barriers();
   reset_emptied_queue();
   for (uint s = 0; s < workers(); s += 1) {
@@ -450,8 +431,6 @@
   assert(queue()->is_empty(), "still have queued work");
   NoopGCTask::destroy(_noop_task);
   _noop_task = NULL;
-  WaitForBarrierGCTask::destroy(_idle_inactive_task);
-  _idle_inactive_task = NULL;
   if (_thread != NULL) {
     for (uint i = 0; i < workers(); i += 1) {
       GCTaskThread::destroy(thread(i));
@@ -507,7 +486,7 @@
       // the GCTaskManager's monitor so that the "more_inactive_workers"
       // count is correct.
       MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
-      _idle_inactive_task->set_should_wait(true);
+      _wait_helper.set_should_wait(true);
       // active_workers are a number being requested.  idle_workers
       // are the number currently idle.  If all the workers are being
       // requested to be active but some are already idle, reduce
@@ -550,7 +529,7 @@
   {
     MutexLockerEx ml(monitor(),
       Mutex::_no_safepoint_check_flag);
-    _idle_inactive_task->set_should_wait(false);
+    _wait_helper.set_should_wait(false);
     monitor()->notify_all();
   // Release monitor
   }
@@ -671,7 +650,6 @@
     // Just hand back a Noop task,
     // in case someone wanted us to release resources, or whatever.
     result = noop_task();
-    increment_noop_tasks();
   }
   assert(result != NULL, "shouldn't have null task");
   if (TraceGCTaskManager) {
@@ -706,11 +684,6 @@
     if (TraceGCTaskManager) {
       tty->print_cr("    GCTaskManager::note_completion(%u) done", which);
     }
-    // Notify client that we are done.
-    NotifyDoneClosure* ndc = notify_done_closure();
-    if (ndc != NULL) {
-      ndc->notify(this);
-    }
   }
   if (TraceGCTaskManager) {
     tty->print_cr("    GCTaskManager::note_completion(%u) (%s)->notify_all",
@@ -751,7 +724,7 @@
 }
 
 void GCTaskManager::release_all_resources() {
-  // If you want this to be done atomically, do it in a BarrierGCTask.
+  // If you want this to be done atomically, do it in a WaitForBarrierGCTask.
   for (uint i = 0; i < workers(); i += 1) {
     set_resource_flag(i, true);
   }
@@ -813,25 +786,22 @@
 // NoopGCTask
 //
 
-NoopGCTask* NoopGCTask::create() {
-  NoopGCTask* result = new NoopGCTask(false);
-  return result;
-}
-
 NoopGCTask* NoopGCTask::create_on_c_heap() {
-  NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask(true);
+  NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask();
   return result;
 }
 
 void NoopGCTask::destroy(NoopGCTask* that) {
   if (that != NULL) {
     that->destruct();
-    if (that->is_c_heap_obj()) {
-      FreeHeap(that);
-    }
+    FreeHeap(that);
   }
 }
 
+// This task should never be performing GC work that require
+// a valid GC id.
+NoopGCTask::NoopGCTask() : GCTask(GCTask::Kind::noop_task, GCId::undefined()) { }
+
 void NoopGCTask::destruct() {
   // This has to know it's superclass structure, just like the constructor.
   this->GCTask::destruct();
@@ -857,12 +827,12 @@
 }
 
 void IdleGCTask::do_it(GCTaskManager* manager, uint which) {
-  WaitForBarrierGCTask* wait_for_task = manager->idle_inactive_task();
+  WaitHelper* wait_helper = manager->wait_helper();
   if (TraceGCTaskManager) {
     tty->print_cr("[" INTPTR_FORMAT "]"
                   " IdleGCTask:::do_it()"
       "  should_wait: %s",
-      p2i(this), wait_for_task->should_wait() ? "true" : "false");
+      p2i(this), wait_helper->should_wait() ? "true" : "false");
   }
   MutexLockerEx ml(manager->monitor(), Mutex::_no_safepoint_check_flag);
   if (TraceDynamicGCThreads) {
@@ -871,7 +841,7 @@
   // Increment has to be done when the idle tasks are created.
   // manager->increment_idle_workers();
   manager->monitor()->notify_all();
-  while (wait_for_task->should_wait()) {
+  while (wait_helper->should_wait()) {
     if (TraceGCTaskManager) {
       tty->print_cr("[" INTPTR_FORMAT "]"
                     " IdleGCTask::do_it()"
@@ -888,7 +858,7 @@
     tty->print_cr("[" INTPTR_FORMAT "]"
                   " IdleGCTask::do_it() returns"
       "  should_wait: %s",
-      p2i(this), wait_for_task->should_wait() ? "true" : "false");
+      p2i(this), wait_helper->should_wait() ? "true" : "false");
   }
   // Release monitor().
 }
@@ -909,140 +879,52 @@
 }
 
 //
-// BarrierGCTask
+// WaitForBarrierGCTask
 //
-
-void BarrierGCTask::do_it(GCTaskManager* manager, uint which) {
-  // Wait for this to be the only busy worker.
-  // ??? I thought of having a StackObj class
-  //     whose constructor would grab the lock and come to the barrier,
-  //     and whose destructor would release the lock,
-  //     but that seems like too much mechanism for two lines of code.
-  MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
-  do_it_internal(manager, which);
-  // Release manager->lock().
+WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
+  WaitForBarrierGCTask* result = new WaitForBarrierGCTask();
+  return result;
 }
 
-void BarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
+WaitForBarrierGCTask::WaitForBarrierGCTask() : GCTask(GCTask::Kind::wait_for_barrier_task) { }
+
+void WaitForBarrierGCTask::destroy(WaitForBarrierGCTask* that) {
+  if (that != NULL) {
+    if (TraceGCTaskManager) {
+      tty->print_cr("[" INTPTR_FORMAT "] WaitForBarrierGCTask::destroy()", p2i(that));
+    }
+    that->destruct();
+  }
+}
+
+void WaitForBarrierGCTask::destruct() {
+  if (TraceGCTaskManager) {
+    tty->print_cr("[" INTPTR_FORMAT "] WaitForBarrierGCTask::destruct()", p2i(this));
+  }
+  this->GCTask::destruct();
+  // Clean up that should be in the destructor,
+  // except that ResourceMarks don't call destructors.
+  _wait_helper.release_monitor();
+}
+
+void WaitForBarrierGCTask::do_it_internal(GCTaskManager* manager, uint which) {
   // Wait for this to be the only busy worker.
   assert(manager->monitor()->owned_by_self(), "don't own the lock");
   assert(manager->is_blocked(), "manager isn't blocked");
   while (manager->busy_workers() > 1) {
     if (TraceGCTaskManager) {
-      tty->print_cr("BarrierGCTask::do_it(%u) waiting on %u workers",
+      tty->print_cr("WaitForBarrierGCTask::do_it(%u) waiting on %u workers",
                     which, manager->busy_workers());
     }
     manager->monitor()->wait(Mutex::_no_safepoint_check_flag, 0);
   }
 }
 
-void BarrierGCTask::destruct() {
-  this->GCTask::destruct();
-  // Nothing else to do.
-}
-
-//
-// ReleasingBarrierGCTask
-//
-
-void ReleasingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
-  MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
-  do_it_internal(manager, which);
-  manager->release_all_resources();
-  // Release manager->lock().
-}
-
-void ReleasingBarrierGCTask::destruct() {
-  this->BarrierGCTask::destruct();
-  // Nothing else to do.
-}
-
-//
-// NotifyingBarrierGCTask
-//
-
-void NotifyingBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
-  MutexLockerEx ml(manager->lock(), Mutex::_no_safepoint_check_flag);
-  do_it_internal(manager, which);
-  NotifyDoneClosure* ndc = notify_done_closure();
-  if (ndc != NULL) {
-    ndc->notify(manager);
-  }
-  // Release manager->lock().
-}
-
-void NotifyingBarrierGCTask::destruct() {
-  this->BarrierGCTask::destruct();
-  // Nothing else to do.
-}
-
-//
-// WaitForBarrierGCTask
-//
-WaitForBarrierGCTask* WaitForBarrierGCTask::create() {
-  WaitForBarrierGCTask* result = new WaitForBarrierGCTask(false);
-  return result;
-}
-
-WaitForBarrierGCTask* WaitForBarrierGCTask::create_on_c_heap() {
-  WaitForBarrierGCTask* result =
-    new (ResourceObj::C_HEAP, mtGC) WaitForBarrierGCTask(true);
-  return result;
-}
-
-WaitForBarrierGCTask::WaitForBarrierGCTask(bool on_c_heap) :
-  _is_c_heap_obj(on_c_heap) {
-  _monitor = MonitorSupply::reserve();
-  set_should_wait(true);
-  if (TraceGCTaskManager) {
-    tty->print_cr("[" INTPTR_FORMAT "]"
-                  " WaitForBarrierGCTask::WaitForBarrierGCTask()"
-                  "  monitor: " INTPTR_FORMAT,
-                  p2i(this), p2i(monitor()));
-  }
-}
-
-void WaitForBarrierGCTask::destroy(WaitForBarrierGCTask* that) {
-  if (that != NULL) {
-    if (TraceGCTaskManager) {
-      tty->print_cr("[" INTPTR_FORMAT "]"
-                    " WaitForBarrierGCTask::destroy()"
-                    "  is_c_heap_obj: %s"
-                    "  monitor: " INTPTR_FORMAT,
-                    p2i(that),
-                    that->is_c_heap_obj() ? "true" : "false",
-                    p2i(that->monitor()));
-    }
-    that->destruct();
-    if (that->is_c_heap_obj()) {
-      FreeHeap(that);
-    }
-  }
-}
-
-void WaitForBarrierGCTask::destruct() {
-  assert(monitor() != NULL, "monitor should not be NULL");
-  if (TraceGCTaskManager) {
-    tty->print_cr("[" INTPTR_FORMAT "]"
-                  " WaitForBarrierGCTask::destruct()"
-                  "  monitor: " INTPTR_FORMAT,
-                  p2i(this), p2i(monitor()));
-  }
-  this->BarrierGCTask::destruct();
-  // Clean up that should be in the destructor,
-  // except that ResourceMarks don't call destructors.
-   if (monitor() != NULL) {
-     MonitorSupply::release(monitor());
-  }
-  _monitor = (Monitor*) 0xDEAD000F;
-}
-
 void WaitForBarrierGCTask::do_it(GCTaskManager* manager, uint which) {
   if (TraceGCTaskManager) {
     tty->print_cr("[" INTPTR_FORMAT "]"
-                  " WaitForBarrierGCTask::do_it() waiting for idle"
-                  "  monitor: " INTPTR_FORMAT,
-                  p2i(this), p2i(monitor()));
+                  " WaitForBarrierGCTask::do_it() waiting for idle",
+                  p2i(this));
   }
   {
     // First, wait for the barrier to arrive.
@@ -1050,24 +932,30 @@
     do_it_internal(manager, which);
     // Release manager->lock().
   }
-  {
-    // Then notify the waiter.
-    MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
-    set_should_wait(false);
-    // Waiter doesn't miss the notify in the wait_for method
-    // since it checks the flag after grabbing the monitor.
-    if (TraceGCTaskManager) {
-      tty->print_cr("[" INTPTR_FORMAT "]"
-                    " WaitForBarrierGCTask::do_it()"
-                    "  [" INTPTR_FORMAT "] (%s)->notify_all()",
-                    p2i(this), p2i(monitor()), monitor()->name());
-    }
-    monitor()->notify_all();
-    // Release monitor().
+  // Then notify the waiter.
+  _wait_helper.notify();
+}
+
+WaitHelper::WaitHelper() : _should_wait(true), _monitor(MonitorSupply::reserve()) {
+  if (TraceGCTaskManager) {
+    tty->print_cr("[" INTPTR_FORMAT "]"
+                  " WaitHelper::WaitHelper()"
+                  "  monitor: " INTPTR_FORMAT,
+                  p2i(this), p2i(monitor()));
   }
 }
 
-void WaitForBarrierGCTask::wait_for(bool reset) {
+void WaitHelper::release_monitor() {
+  assert(_monitor != NULL, "");
+  MonitorSupply::release(_monitor);
+  _monitor = NULL;
+}
+
+WaitHelper::~WaitHelper() {
+  release_monitor();
+}
+
+void WaitHelper::wait_for(bool reset) {
   if (TraceGCTaskManager) {
     tty->print_cr("[" INTPTR_FORMAT "]"
                   " WaitForBarrierGCTask::wait_for()"
@@ -1100,6 +988,20 @@
   }
 }
 
+void WaitHelper::notify() {
+  MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
+  set_should_wait(false);
+  // Waiter doesn't miss the notify in the wait_for method
+  // since it checks the flag after grabbing the monitor.
+  if (TraceGCTaskManager) {
+    tty->print_cr("[" INTPTR_FORMAT "]"
+                  " WaitForBarrierGCTask::do_it()"
+                  "  [" INTPTR_FORMAT "] (%s)->notify_all()",
+                  p2i(this), p2i(monitor()), monitor()->name());
+  }
+  monitor()->notify_all();
+}
+
 Mutex*                   MonitorSupply::_lock     = NULL;
 GrowableArray<Monitor*>* MonitorSupply::_freelist = NULL;
 
--- a/src/share/vm/gc/parallel/gcTaskManager.hpp	Tue Oct 06 14:27:39 2015 -0400
+++ b/src/share/vm/gc/parallel/gcTaskManager.hpp	Tue Oct 06 18:51:47 2015 +0000
@@ -38,12 +38,8 @@
 class GCTaskQueue;
 class SynchronizedGCTaskQueue;
 class GCTaskManager;
-class NotifyDoneClosure;
 // Some useful subclasses of GCTask.  You can also make up your own.
 class NoopGCTask;
-class BarrierGCTask;
-class ReleasingBarrierGCTask;
-class NotifyingBarrierGCTask;
 class WaitForBarrierGCTask;
 class IdleGCTask;
 // A free list of Monitor*'s.
@@ -64,7 +60,7 @@
     enum kind {
       unknown_task,
       ordinary_task,
-      barrier_task,
+      wait_for_barrier_task,
       noop_task,
       idle_task
     };
@@ -72,13 +68,16 @@
   };
 private:
   // Instance state.
-  const Kind::kind _kind;               // For runtime type checking.
-  const uint       _affinity;           // Which worker should run task.
+  Kind::kind       _kind;               // For runtime type checking.
+  uint             _affinity;           // Which worker should run task.
   GCTask*          _newer;              // Tasks are on doubly-linked ...
   GCTask*          _older;              // ... lists.
+  uint             _gc_id;              // GC Id to use for the thread that executes this task
 public:
   virtual char* name() { return (char *)"task"; }
 
+  uint gc_id() { return _gc_id; }
+
   // Abstract do_it method
   virtual void do_it(GCTaskManager* manager, uint which) = 0;
   // Accessors
@@ -105,7 +104,7 @@
     return kind()==Kind::ordinary_task;
   }
   bool is_barrier_task() const {
-    return kind()==Kind::barrier_task;
+    return kind()==Kind::wait_for_barrier_task;
   }
   bool is_noop_task() const {
     return kind()==Kind::noop_task;
@@ -120,17 +119,14 @@
   GCTask();
   //     A GCTask of a particular kind, usually barrier or noop.
   GCTask(Kind::kind kind);
-  //     An ordinary GCTask with an affinity.
-  GCTask(uint affinity);
-  //     A GCTask of a particular kind, with and affinity.
-  GCTask(Kind::kind kind, uint affinity);
+  GCTask(Kind::kind kind, uint gc_id);
   // We want a virtual destructor because virtual methods,
   // but since ResourceObj's don't have their destructors
   // called, we don't have one at all.  Instead we have
   // this method, which gets called by subclasses to clean up.
   virtual void destruct();
   // Methods.
-  void initialize();
+  void initialize(Kind::kind kind, uint gc_id);
 };
 
 // A doubly-linked list of GCTasks.
@@ -276,21 +272,26 @@
   ~SynchronizedGCTaskQueue();
 };
 
-// This is an abstract base class for getting notifications
-// when a GCTaskManager is done.
-class NotifyDoneClosure : public CHeapObj<mtGC> {
-public:
-  // The notification callback method.
-  virtual void notify(GCTaskManager* manager) = 0;
-protected:
-  // Constructor.
-  NotifyDoneClosure() {
-    // Nothing to do.
+class WaitHelper VALUE_OBJ_CLASS_SPEC {
+ private:
+  Monitor*      _monitor;
+  volatile bool _should_wait;
+ public:
+  WaitHelper();
+  ~WaitHelper();
+  void wait_for(bool reset);
+  void notify();
+  void set_should_wait(bool value) {
+    _should_wait = value;
   }
-  // Virtual destructor because virtual methods.
-  virtual ~NotifyDoneClosure() {
-    // Nothing to do.
+
+  Monitor* monitor() const {
+    return _monitor;
   }
+  bool should_wait() const {
+    return _should_wait;
+  }
+  void release_monitor();
 };
 
 // Dynamic number of GC threads
@@ -365,7 +366,6 @@
  friend class IdleGCTask;
 private:
   // Instance state.
-  NotifyDoneClosure*        _ndc;               // Notify on completion.
   const uint                _workers;           // Number of workers.
   Monitor*                  _monitor;           // Notification of changes.
   SynchronizedGCTaskQueue*  _queue;             // Queue of tasks.
@@ -379,17 +379,13 @@
   uint                      _barriers;          // Count of barrier tasks.
   uint                      _emptied_queue;     // Times we emptied the queue.
   NoopGCTask*               _noop_task;         // The NoopGCTask instance.
-  uint                      _noop_tasks;        // Count of noop tasks.
-  WaitForBarrierGCTask*     _idle_inactive_task;// Task for inactive workers
+  WaitHelper                _wait_helper;       // Used by inactive worker
   volatile uint             _idle_workers;      // Number of idled workers
 public:
   // Factory create and destroy methods.
   static GCTaskManager* create(uint workers) {
     return new GCTaskManager(workers);
   }
-  static GCTaskManager* create(uint workers, NotifyDoneClosure* ndc) {
-    return new GCTaskManager(workers, ndc);
-  }
   static void destroy(GCTaskManager* that) {
     if (that != NULL) {
       delete that;
@@ -409,8 +405,8 @@
   Monitor * lock() const {
     return _monitor;
   }
-  WaitForBarrierGCTask* idle_inactive_task() {
-    return _idle_inactive_task;
+  WaitHelper* wait_helper() {
+    return &_wait_helper;
   }
   // Methods.
   //     Add the argument task to be run.
@@ -452,8 +448,6 @@
   // Constructors.  Clients use factory, but there might be subclasses.
   //     Create a GCTaskManager with the appropriate number of workers.
   GCTaskManager(uint workers);
-  //     Create a GCTaskManager that calls back when there's no more work.
-  GCTaskManager(uint workers, NotifyDoneClosure* ndc);
   //     Make virtual if necessary.
   ~GCTaskManager();
   // Accessors.
@@ -469,9 +463,6 @@
   // Sets the number of threads that will be used in a collection
   void set_active_gang();
 
-  NotifyDoneClosure* notify_done_closure() const {
-    return _ndc;
-  }
   SynchronizedGCTaskQueue* queue() const {
     return _queue;
   }
@@ -540,17 +531,6 @@
   void reset_emptied_queue() {
     _emptied_queue = 0;
   }
-  //     Count of the number of noop tasks we've handed out,
-  //     e.g., to handle resource release requests.
-  uint noop_tasks() const {
-    return _noop_tasks;
-  }
-  void increment_noop_tasks() {
-    _noop_tasks += 1;
-  }
-  void reset_noop_tasks() {
-    _noop_tasks = 0;
-  }
   void increment_idle_workers() {
     _idle_workers++;
   }
@@ -575,11 +555,8 @@
 // A noop task that does nothing,
 // except take us around the GCTaskThread loop.
 class NoopGCTask : public GCTask {
-private:
-  const bool _is_c_heap_obj;            // Is this a CHeapObj?
 public:
   // Factory create and destroy methods.
-  static NoopGCTask* create();
   static NoopGCTask* create_on_c_heap();
   static void destroy(NoopGCTask* that);
 
@@ -590,147 +567,39 @@
   }
 protected:
   // Constructor.
-  NoopGCTask(bool on_c_heap) :
-    GCTask(GCTask::Kind::noop_task),
-    _is_c_heap_obj(on_c_heap) {
-    // Nothing to do.
-  }
-  // Destructor-like method.
-  void destruct();
-  // Accessors.
-  bool is_c_heap_obj() const {
-    return _is_c_heap_obj;
-  }
-};
-
-// A BarrierGCTask blocks other tasks from starting,
-// and waits until it is the only task running.
-class BarrierGCTask : public GCTask {
-public:
-  // Factory create and destroy methods.
-  static BarrierGCTask* create() {
-    return new BarrierGCTask();
-  }
-  static void destroy(BarrierGCTask* that) {
-    if (that != NULL) {
-      that->destruct();
-      delete that;
-    }
-  }
-  // Methods from GCTask.
-  void do_it(GCTaskManager* manager, uint which);
-protected:
-  // Constructor.  Clients use factory, but there might be subclasses.
-  BarrierGCTask() :
-    GCTask(GCTask::Kind::barrier_task) {
-    // Nothing to do.
-  }
-  // Destructor-like method.
-  void destruct();
-
-  virtual char* name() { return (char *)"barrier task"; }
-  // Methods.
-  //     Wait for this to be the only task running.
-  void do_it_internal(GCTaskManager* manager, uint which);
-};
-
-// A ReleasingBarrierGCTask is a BarrierGCTask
-// that tells all the tasks to release their resource areas.
-class ReleasingBarrierGCTask : public BarrierGCTask {
-public:
-  // Factory create and destroy methods.
-  static ReleasingBarrierGCTask* create() {
-    return new ReleasingBarrierGCTask();
-  }
-  static void destroy(ReleasingBarrierGCTask* that) {
-    if (that != NULL) {
-      that->destruct();
-      delete that;
-    }
-  }
-  // Methods from GCTask.
-  void do_it(GCTaskManager* manager, uint which);
-protected:
-  // Constructor.  Clients use factory, but there might be subclasses.
-  ReleasingBarrierGCTask() :
-    BarrierGCTask() {
-    // Nothing to do.
-  }
+  NoopGCTask();
   // Destructor-like method.
   void destruct();
 };
 
-// A NotifyingBarrierGCTask is a BarrierGCTask
-// that calls a notification method when it is the only task running.
-class NotifyingBarrierGCTask : public BarrierGCTask {
-private:
-  // Instance state.
-  NotifyDoneClosure* _ndc;              // The callback object.
-public:
-  // Factory create and destroy methods.
-  static NotifyingBarrierGCTask* create(NotifyDoneClosure* ndc) {
-    return new NotifyingBarrierGCTask(ndc);
-  }
-  static void destroy(NotifyingBarrierGCTask* that) {
-    if (that != NULL) {
-      that->destruct();
-      delete that;
-    }
-  }
-  // Methods from GCTask.
-  void do_it(GCTaskManager* manager, uint which);
-protected:
-  // Constructor.  Clients use factory, but there might be subclasses.
-  NotifyingBarrierGCTask(NotifyDoneClosure* ndc) :
-    BarrierGCTask(),
-    _ndc(ndc) {
-    assert(notify_done_closure() != NULL, "can't notify on NULL");
-  }
-  // Destructor-like method.
-  void destruct();
-  // Accessor.
-  NotifyDoneClosure* notify_done_closure() const { return _ndc; }
-};
-
-// A WaitForBarrierGCTask is a BarrierGCTask
+// A WaitForBarrierGCTask is a GCTask
 // with a method you can call to wait until
 // the BarrierGCTask is done.
-// This may cover many of the uses of NotifyingBarrierGCTasks.
-class WaitForBarrierGCTask : public BarrierGCTask {
+class WaitForBarrierGCTask : public GCTask {
   friend class GCTaskManager;
   friend class IdleGCTask;
 private:
   // Instance state.
-  Monitor*      _monitor;                  // Guard and notify changes.
-  volatile bool _should_wait;              // true=>wait, false=>proceed.
-  const bool    _is_c_heap_obj;            // Was allocated on the heap.
+  WaitHelper    _wait_helper;
+  WaitForBarrierGCTask();
 public:
   virtual char* name() { return (char *) "waitfor-barrier-task"; }
 
   // Factory create and destroy methods.
   static WaitForBarrierGCTask* create();
-  static WaitForBarrierGCTask* create_on_c_heap();
   static void destroy(WaitForBarrierGCTask* that);
   // Methods.
   void     do_it(GCTaskManager* manager, uint which);
-  void     wait_for(bool reset);
-  void set_should_wait(bool value) {
-    _should_wait = value;
-  }
 protected:
-  // Constructor.  Clients use factory, but there might be subclasses.
-  WaitForBarrierGCTask(bool on_c_heap);
   // Destructor-like method.
   void destruct();
-  // Accessors.
-  Monitor* monitor() const {
-    return _monitor;
-  }
-  bool should_wait() const {
-    return _should_wait;
-  }
-  bool is_c_heap_obj() {
-    return _is_c_heap_obj;
+
+  // Methods.
+  //     Wait for this to be the only task running.
+  void do_it_internal(GCTaskManager* manager, uint which);
+
+  void wait_for(bool reset) {
+    _wait_helper.wait_for(reset);
   }
 };
 
--- a/src/share/vm/gc/parallel/gcTaskThread.cpp	Tue Oct 06 14:27:39 2015 -0400
+++ b/src/share/vm/gc/parallel/gcTaskThread.cpp	Tue Oct 06 18:51:47 2015 +0000
@@ -26,6 +26,7 @@
 #include "precompiled.hpp"
 #include "gc/parallel/gcTaskManager.hpp"
 #include "gc/parallel/gcTaskThread.hpp"
+#include "gc/shared/gcId.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
@@ -124,6 +125,7 @@
     for (; /* break */; ) {
       // This will block until there is a task to be gotten.
       GCTask* task = manager()->get_task(which());
+      GCIdMark gc_id_mark(task->gc_id());
       // Record if this is an idle task for later use.
       bool is_idle_task = task->is_idle_task();
       // In case the update is costly