1/*
2 * Copyright (c) 2002, 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_PSTASKS_HPP
26#define SHARE_GC_PARALLEL_PSTASKS_HPP
27
28#include "utilities/growableArray.hpp"
29
30//
31// psTasks.hpp is a collection of GCTasks used by the
32// parallelScavenge collector.
33//
34
35class GCTask;
36class OopClosure;
37class OopStack;
38class ObjectStartArray;
39class ParallelTaskTerminator;
40class MutableSpace;
41class PSOldGen;
42class Thread;
43class VMThread;
44
45//
46// ScavengeRootsTask
47//
48// This task scans all the roots of a given type.
49//
50//
51
52class ScavengeRootsTask : public GCTask {
53 public:
54 enum RootType {
55 universe = 1,
56 jni_handles = 2,
57 threads = 3,
58 object_synchronizer = 4,
59 system_dictionary = 5,
60 class_loader_data = 6,
61 management = 7,
62 jvmti = 8,
63 code_cache = 9
64 JVMCI_ONLY(COMMA jvmci = 10)
65 };
66 private:
67 RootType _root_type;
68 public:
69 ScavengeRootsTask(RootType value) : _root_type(value) {}
70
71 char* name() { return (char *)"scavenge-roots-task"; }
72
73 virtual void do_it(GCTaskManager* manager, uint which);
74};
75
76//
77// ThreadRootsTask
78//
79// This task scans the roots of a single thread. This task
80// enables scanning of thread roots in parallel.
81//
82
83class ThreadRootsTask : public GCTask {
84 private:
85 Thread* _thread;
86
87 public:
88 ThreadRootsTask(Thread* root) : _thread(root) {}
89
90 char* name() { return (char *)"thread-roots-task"; }
91
92 virtual void do_it(GCTaskManager* manager, uint which);
93};
94
95//
96// StealTask
97//
98// This task is used to distribute work to idle threads.
99//
100
101class StealTask : public GCTask {
102 private:
103 ParallelTaskTerminator* const _terminator;
104 public:
105 char* name() { return (char *)"steal-task"; }
106
107 StealTask(ParallelTaskTerminator* t);
108
109 ParallelTaskTerminator* terminator() { return _terminator; }
110
111 virtual void do_it(GCTaskManager* manager, uint which);
112};
113
114//
115// OldToYoungRootsTask
116//
117// This task is used to scan old to young roots in parallel
118//
119// A GC thread executing this tasks divides the generation (old gen)
120// into slices and takes a stripe in the slice as its part of the
121// work.
122//
123// +===============+ slice 0
124// | stripe 0 |
125// +---------------+
126// | stripe 1 |
127// +---------------+
128// | stripe 2 |
129// +---------------+
130// | stripe 3 |
131// +===============+ slice 1
132// | stripe 0 |
133// +---------------+
134// | stripe 1 |
135// +---------------+
136// | stripe 2 |
137// +---------------+
138// | stripe 3 |
139// +===============+ slice 2
140// ...
141//
142// A task is created for each stripe. In this case there are 4 tasks
143// created. A GC thread first works on its stripe within slice 0
144// and then moves to its stripe in the next slice until all stripes
145// exceed the top of the generation. Note that having fewer GC threads
146// than stripes works because all the tasks are executed so all stripes
147// will be covered. In this example if 4 tasks have been created to cover
148// all the stripes and there are only 3 threads, one of the threads will
149// get the tasks with the 4th stripe. However, there is a dependence in
150// PSCardTable::scavenge_contents_parallel() on the number
151// of tasks created. In scavenge_contents_parallel the distance
152// to the next stripe is calculated based on the number of tasks.
153// If the stripe width is ssize, a task's next stripe is at
154// ssize * number_of_tasks (= slice_stride). In this case after
155// finishing stripe 0 in slice 0, the thread finds the stripe 0 in slice1
156// by adding slice_stride to the start of stripe 0 in slice 0 to get
157// to the start of stride 0 in slice 1.
158
159class OldToYoungRootsTask : public GCTask {
160 private:
161 PSOldGen* _old_gen;
162 HeapWord* _gen_top;
163 uint _stripe_number;
164 uint _stripe_total;
165
166 public:
167 OldToYoungRootsTask(PSOldGen *old_gen,
168 HeapWord* gen_top,
169 uint stripe_number,
170 uint stripe_total) :
171 _old_gen(old_gen),
172 _gen_top(gen_top),
173 _stripe_number(stripe_number),
174 _stripe_total(stripe_total) { }
175
176 char* name() { return (char *)"old-to-young-roots-task"; }
177
178 virtual void do_it(GCTaskManager* manager, uint which);
179};
180
181#endif // SHARE_GC_PARALLEL_PSTASKS_HPP
182