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
66class ParallelTaskTerminator;
67
68class 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
90class 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
119class RefProcTaskProxy : public GCTask {
120  typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
121  ProcessTask & _rp_task;
122  uint          _work_id;
123public:
124  RefProcTaskProxy(ProcessTask & rp_task, uint work_id)
125    : _rp_task(rp_task),
126      _work_id(work_id)
127  { }
128
129private:
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
143class RefEnqueueTaskProxy: public GCTask {
144  typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
145  EnqueueTask& _enq_task;
146  uint         _work_id;
147
148public:
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
169class 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
181class 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
202class 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
221class 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
237