1 /*
   2  * Copyright (c) 2005, 2019, 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_GC_PARALLEL_PCTASKS_HPP
  26 #define SHARE_GC_PARALLEL_PCTASKS_HPP
  27 
  28 #include "gc/parallel/gcTaskManager.hpp"
  29 #include "gc/parallel/psParallelCompact.hpp"
  30 #include "gc/parallel/psTasks.hpp"
  31 #include "gc/shared/referenceProcessor.hpp"
  32 
  33 
  34 // Tasks for parallel compaction of the old generation
  35 //
  36 // Tasks are created and enqueued on a task queue. The
  37 // tasks for parallel old collector for marking objects
  38 // are MarkFromRootsTask and ThreadRootsMarkingTask.
  39 //
  40 // MarkFromRootsTask's are created
  41 // with a root group (e.g., jni_handles) and when the do_it()
  42 // method of a MarkFromRootsTask is executed, it starts marking
  43 // form it's root group.
  44 //
  45 // ThreadRootsMarkingTask's are created for each Java thread.  When
  46 // the do_it() method of a ThreadRootsMarkingTask is executed, it
  47 // starts marking from the thread's roots.
  48 //
  49 // The enqueueing of the MarkFromRootsTask and ThreadRootsMarkingTask
  50 // do little more than create the task and put it on a queue.  The
  51 // queue is a GCTaskQueue and threads steal tasks from this GCTaskQueue.
  52 //
  53 // In addition to the MarkFromRootsTask and ThreadRootsMarkingTask
  54 // tasks there are StealMarkingTask tasks.  The StealMarkingTask's
  55 // steal a reference from the marking stack of another
  56 // thread and transitively marks the object of the reference
  57 // and internal references.  After successfully stealing a reference
  58 // and marking it, the StealMarkingTask drains its marking stack
  59 // stack before attempting another steal.
  60 //
  61 // ThreadRootsMarkingTask
  62 //
  63 // This task marks from the roots of a single thread. This task
  64 // enables marking of thread roots in parallel.
  65 //
  66 
  67 class ParallelTaskTerminator;
  68 
  69 class ThreadRootsMarkingTask : public GCTask {
  70  private:
  71   Thread* _thread;
  72 
  73  public:
  74   ThreadRootsMarkingTask(Thread* root) : _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     JVMCI_ONLY(COMMA jvmci = 10)
 103   };
 104  private:
 105   RootType _root_type;
 106  public:
 107   MarkFromRootsTask(RootType value) : _root_type(value) {}
 108 
 109   char* name() { return (char *)"mark-from-roots-task"; }
 110 
 111   virtual void do_it(GCTaskManager* manager, uint which);
 112 };
 113 
 114 //
 115 // RefProcTaskProxy
 116 //
 117 // This task is used as a proxy to parallel reference processing tasks .
 118 //
 119 
 120 class RefProcTaskProxy : public GCTask {
 121   typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
 122   ProcessTask & _rp_task;
 123   uint          _work_id;
 124 public:
 125   RefProcTaskProxy(ProcessTask & rp_task, uint work_id)
 126     : _rp_task(rp_task),
 127       _work_id(work_id)
 128   { }
 129 
 130 private:
 131   virtual char* name() { return (char *)"Process referents by policy in parallel"; }
 132 
 133   virtual void do_it(GCTaskManager* manager, uint which);
 134 };
 135 
 136 
 137 //
 138 // RefProcTaskExecutor
 139 //
 140 // Task executor is an interface for the reference processor to run
 141 // tasks using GCTaskManager.
 142 //
 143 
 144 class RefProcTaskExecutor: public AbstractRefProcTaskExecutor {
 145   virtual void execute(ProcessTask& task, uint ergo_workers);
 146 };
 147 
 148 
 149 //
 150 // StealMarkingTask
 151 //
 152 // This task is used to distribute work to idle threads.
 153 //
 154 
 155 class StealMarkingTask : public GCTask {
 156  private:
 157    ParallelTaskTerminator* const _terminator;
 158  private:
 159 
 160  public:
 161   char* name() { return (char *)"steal-marking-task"; }
 162 
 163   StealMarkingTask(ParallelTaskTerminator* t);
 164 
 165   ParallelTaskTerminator* terminator() { return _terminator; }
 166 
 167   virtual void do_it(GCTaskManager* manager, uint which);
 168 };
 169 
 170 //
 171 // CompactionWithStealingTask
 172 //
 173 // This task is used to distribute work to idle threads.
 174 //
 175 
 176 class CompactionWithStealingTask : public GCTask {
 177  private:
 178    ParallelTaskTerminator* const _terminator;
 179  public:
 180   CompactionWithStealingTask(ParallelTaskTerminator* t);
 181 
 182   char* name() { return (char *)"steal-region-task"; }
 183   ParallelTaskTerminator* terminator() { return _terminator; }
 184 
 185   virtual void do_it(GCTaskManager* manager, uint which);
 186 };
 187 
 188 //
 189 // UpdateDensePrefixTask
 190 //
 191 // This task is used to update the dense prefix
 192 // of a space.
 193 //
 194 
 195 class UpdateDensePrefixTask : public GCTask {
 196  private:
 197   PSParallelCompact::SpaceId _space_id;
 198   size_t _region_index_start;
 199   size_t _region_index_end;
 200 
 201  public:
 202   char* name() { return (char *)"update-dense_prefix-task"; }
 203 
 204   UpdateDensePrefixTask(PSParallelCompact::SpaceId space_id,
 205                         size_t region_index_start,
 206                         size_t region_index_end);
 207 
 208   virtual void do_it(GCTaskManager* manager, uint which);
 209 };
 210 #endif // SHARE_GC_PARALLEL_PCTASKS_HPP