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