1 /*
   2  * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_GC_PARALLEL_PCTASKS_HPP
  26 #define SHARE_VM_GC_PARALLEL_PCTASKS_HPP
  27 
  28 #include "gc/parallel/gcTaskManager.hpp"
  29 #include "gc/parallel/psParallelCompact.hpp"
  30 #include "gc/parallel/psTasks.hpp"
  31 
  32 
  33 // Tasks for parallel compaction of the old generation
  34 //
  35 // Tasks are created and enqueued on a task queue. The
  36 // tasks for parallel old collector for marking objects
  37 // are MarkFromRootsTask and ThreadRootsMarkingTask.
  38 //
  39 // MarkFromRootsTask's are created
  40 // with a root group (e.g., jni_handles) and when the do_it()
  41 // method of a MarkFromRootsTask is executed, it starts marking
  42 // form it's root group.
  43 //
  44 // ThreadRootsMarkingTask's are created for each Java thread.  When
  45 // the do_it() method of a ThreadRootsMarkingTask is executed, it
  46 // starts marking from the thread's roots.
  47 //
  48 // The enqueueing of the MarkFromRootsTask and ThreadRootsMarkingTask
  49 // do little more than create the task and put it on a queue.  The
  50 // queue is a GCTaskQueue and threads steal tasks from this GCTaskQueue.
  51 //
  52 // In addition to the MarkFromRootsTask and ThreadRootsMarkingTask
  53 // tasks there are StealMarkingTask tasks.  The StealMarkingTask's
  54 // steal a reference from the marking stack of another
  55 // thread and transitively marks the object of the reference
  56 // and internal references.  After successfully stealing a reference
  57 // and marking it, the StealMarkingTask drains its marking stack
  58 // stack before attempting another steal.
  59 //
  60 // ThreadRootsMarkingTask
  61 //
  62 // This task marks from the roots of a single thread. This task
  63 // enables marking of thread roots in parallel.
  64 //
  65 
  66 class ParallelTaskTerminator;
  67 
  68 class ThreadRootsMarkingTask : public GCTask {
  69  private:
  70   JavaThread* _java_thread;
  71   VMThread* _vm_thread;
  72  public:
  73   ThreadRootsMarkingTask(JavaThread* root) : _java_thread(root), _vm_thread(NULL) {}
  74   ThreadRootsMarkingTask(VMThread* root) : _java_thread(NULL), _vm_thread(root) {}
  75 
  76   char* name() { return (char *)"thread-roots-marking-task"; }
  77 
  78   virtual void do_it(GCTaskManager* manager, uint which);
  79 };
  80 
  81 
  82 //
  83 // MarkFromRootsTask
  84 //
  85 // This task marks from all the roots to all live
  86 // objects.
  87 //
  88 //
  89 
  90 class MarkFromRootsTask : public GCTask {
  91  public:
  92   enum RootType {
  93     universe              = 1,
  94     jni_handles           = 2,
  95     threads               = 3,
  96     object_synchronizer   = 4,
  97     management            = 5,
  98     jvmti                 = 6,
  99     system_dictionary     = 7,
 100     class_loader_data     = 8,
 101     code_cache            = 9
 102   };
 103  private:
 104   RootType _root_type;
 105  public:
 106   MarkFromRootsTask(RootType value) : _root_type(value) {}
 107 
 108   char* name() { return (char *)"mark-from-roots-task"; }
 109 
 110   virtual void do_it(GCTaskManager* manager, uint which);
 111 };
 112 
 113 //
 114 // RefProcTaskProxy
 115 //
 116 // This task is used as a proxy to parallel reference processing tasks .
 117 //
 118 
 119 class RefProcTaskProxy : public GCTask {
 120   typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
 121   ProcessTask & _rp_task;
 122   uint          _work_id;
 123 public:
 124   RefProcTaskProxy(ProcessTask & rp_task, uint work_id)
 125     : _rp_task(rp_task),
 126       _work_id(work_id)
 127   { }
 128 
 129 private:
 130   virtual char* name() { return (char *)"Process referents by policy in parallel"; }
 131 
 132   virtual void do_it(GCTaskManager* manager, uint which);
 133 };
 134 
 135 
 136 
 137 //
 138 // RefEnqueueTaskProxy
 139 //
 140 // This task is used as a proxy to parallel reference processing tasks .
 141 //
 142 
 143 class RefEnqueueTaskProxy: public GCTask {
 144   typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
 145   EnqueueTask& _enq_task;
 146   uint         _work_id;
 147 
 148 public:
 149   RefEnqueueTaskProxy(EnqueueTask& enq_task, uint work_id)
 150     : _enq_task(enq_task),
 151       _work_id(work_id)
 152   { }
 153 
 154   virtual char* name() { return (char *)"Enqueue reference objects in parallel"; }
 155   virtual void do_it(GCTaskManager* manager, uint which)
 156   {
 157     _enq_task.work(_work_id);
 158   }
 159 };
 160 
 161 
 162 //
 163 // RefProcTaskExecutor
 164 //
 165 // Task executor is an interface for the reference processor to run
 166 // tasks using GCTaskManager.
 167 //
 168 
 169 class RefProcTaskExecutor: public AbstractRefProcTaskExecutor {
 170   virtual void execute(ProcessTask& task);
 171   virtual void execute(EnqueueTask& task);
 172 };
 173 
 174 
 175 //
 176 // StealMarkingTask
 177 //
 178 // This task is used to distribute work to idle threads.
 179 //
 180 
 181 class StealMarkingTask : public GCTask {
 182  private:
 183    ParallelTaskTerminator* const _terminator;
 184  private:
 185 
 186  public:
 187   char* name() { return (char *)"steal-marking-task"; }
 188 
 189   StealMarkingTask(ParallelTaskTerminator* t);
 190 
 191   ParallelTaskTerminator* terminator() { return _terminator; }
 192 
 193   virtual void do_it(GCTaskManager* manager, uint which);
 194 };
 195 
 196 //
 197 // CompactionWithStealingTask
 198 //
 199 // This task is used to distribute work to idle threads.
 200 //
 201 
 202 class CompactionWithStealingTask : public GCTask {
 203  private:
 204    ParallelTaskTerminator* const _terminator;
 205  public:
 206   CompactionWithStealingTask(ParallelTaskTerminator* t);
 207 
 208   char* name() { return (char *)"steal-region-task"; }
 209   ParallelTaskTerminator* terminator() { return _terminator; }
 210 
 211   virtual void do_it(GCTaskManager* manager, uint which);
 212 };
 213 
 214 //
 215 // UpdateDensePrefixTask
 216 //
 217 // This task is used to update the dense prefix
 218 // of a space.
 219 //
 220 
 221 class UpdateDensePrefixTask : public GCTask {
 222  private:
 223   PSParallelCompact::SpaceId _space_id;
 224   size_t _region_index_start;
 225   size_t _region_index_end;
 226 
 227  public:
 228   char* name() { return (char *)"update-dense_prefix-task"; }
 229 
 230   UpdateDensePrefixTask(PSParallelCompact::SpaceId space_id,
 231                         size_t region_index_start,
 232                         size_t region_index_end);
 233 
 234   virtual void do_it(GCTaskManager* manager, uint which);
 235 };
 236 #endif // SHARE_VM_GC_PARALLEL_PCTASKS_HPP