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_PSCOMPACTIONMANAGER_HPP
26#define SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
27
28#include "gc/shared/taskqueue.hpp"
29#include "memory/allocation.hpp"
30#include "utilities/stack.hpp"
31
32class MutableSpace;
33class PSOldGen;
34class ParCompactionManager;
35class ObjectStartArray;
36class ParallelCompactData;
37class ParMarkBitMap;
38
39class ParCompactionManager : public CHeapObj<mtGC> {
40 friend class ParallelTaskTerminator;
41 friend class ParMarkBitMap;
42 friend class PSParallelCompact;
43 friend class CompactionWithStealingTask;
44 friend class UpdateAndFillClosure;
45 friend class RefProcTaskExecutor;
46 friend class IdleGCTask;
47
48 public:
49
50// ------------------------ Don't putback if not needed
51 // Actions that the compaction manager should take.
52 enum Action {
53 Update,
54 Copy,
55 UpdateAndCopy,
56 CopyAndUpdate,
57 NotValid
58 };
59// ------------------------ End don't putback if not needed
60
61 private:
62 // 32-bit: 4K * 8 = 32KiB; 64-bit: 8K * 16 = 128KiB
63 #define QUEUE_SIZE (1 << NOT_LP64(12) LP64_ONLY(13))
64 typedef OverflowTaskQueue<ObjArrayTask, mtGC, QUEUE_SIZE> ObjArrayTaskQueue;
65 typedef GenericTaskQueueSet<ObjArrayTaskQueue, mtGC> ObjArrayTaskQueueSet;
66 #undef QUEUE_SIZE
67
68 static ParCompactionManager** _manager_array;
69 static OopTaskQueueSet* _stack_array;
70 static ObjArrayTaskQueueSet* _objarray_queues;
71 static ObjectStartArray* _start_array;
72 static RegionTaskQueueSet* _region_array;
73 static PSOldGen* _old_gen;
74
75private:
76 OverflowTaskQueue<oop, mtGC> _marking_stack;
77 ObjArrayTaskQueue _objarray_stack;
78
79 // Is there a way to reuse the _marking_stack for the
80 // saving empty regions? For now just create a different
81 // type of TaskQueue.
82 RegionTaskQueue _region_stack;
83
84 static ParMarkBitMap* _mark_bitmap;
85
86 Action _action;
87
88 HeapWord* _last_query_beg;
89 oop _last_query_obj;
90 size_t _last_query_ret;
91
92 static PSOldGen* old_gen() { return _old_gen; }
93 static ObjectStartArray* start_array() { return _start_array; }
94 static OopTaskQueueSet* stack_array() { return _stack_array; }
95
96 static void initialize(ParMarkBitMap* mbm);
97
98 protected:
99 // Array of tasks. Needed by the ParallelTaskTerminator.
100 static RegionTaskQueueSet* region_array() { return _region_array; }
101 OverflowTaskQueue<oop, mtGC>* marking_stack() { return &_marking_stack; }
102
103 // Pushes onto the marking stack. If the marking stack is full,
104 // pushes onto the overflow stack.
105 void stack_push(oop obj);
106 // Do not implement an equivalent stack_pop. Deal with the
107 // marking stack and overflow stack directly.
108
109 public:
110 void reset_bitmap_query_cache() {
111 _last_query_beg = NULL;
112 _last_query_obj = NULL;
113 _last_query_ret = 0;
114 }
115
116 Action action() { return _action; }
117 void set_action(Action v) { _action = v; }
118
119 // Bitmap query support, cache last query and result
120 HeapWord* last_query_begin() { return _last_query_beg; }
121 oop last_query_object() { return _last_query_obj; }
122 size_t last_query_return() { return _last_query_ret; }
123
124 void set_last_query_begin(HeapWord *new_beg) { _last_query_beg = new_beg; }
125 void set_last_query_object(oop new_obj) { _last_query_obj = new_obj; }
126 void set_last_query_return(size_t new_ret) { _last_query_ret = new_ret; }
127
128 static void reset_all_bitmap_query_caches();
129
130 RegionTaskQueue* region_stack() { return &_region_stack; }
131
132 inline static ParCompactionManager* manager_array(uint index);
133
134 ParCompactionManager();
135
136 // Pushes onto the region stack at the given index. If the
137 // region stack is full,
138 // pushes onto the region overflow stack.
139 static void verify_region_list_empty(uint stack_index);
140 ParMarkBitMap* mark_bitmap() { return _mark_bitmap; }
141
142 // void drain_stacks();
143
144 bool should_update();
145 bool should_copy();
146
147 // Save for later processing. Must not fail.
148 inline void push(oop obj);
149 inline void push_objarray(oop objarray, size_t index);
150 inline void push_region(size_t index);
151
152 // Check mark and maybe push on marking stack.
153 template <typename T> inline void mark_and_push(T* p);
154
155 inline void follow_klass(Klass* klass);
156
157 void follow_class_loader(ClassLoaderData* klass);
158
159 // Access function for compaction managers
160 static ParCompactionManager* gc_thread_compaction_manager(uint index);
161
162 static bool steal(int queue_num, oop& t);
163 static bool steal_objarray(int queue_num, ObjArrayTask& t);
164 static bool steal(int queue_num, size_t& region);
165
166 // Process tasks remaining on any marking stack
167 void follow_marking_stacks();
168 inline bool marking_stacks_empty() const;
169
170 // Process tasks remaining on any stack
171 void drain_region_stacks();
172
173 void follow_contents(oop obj);
174 void follow_array(objArrayOop array, int index);
175
176 void update_contents(oop obj);
177
178 class FollowStackClosure: public VoidClosure {
179 private:
180 ParCompactionManager* _compaction_manager;
181 public:
182 FollowStackClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
183 virtual void do_void();
184 };
185};
186
187inline ParCompactionManager* ParCompactionManager::manager_array(uint index) {
188 assert(_manager_array != NULL, "access of NULL manager_array");
189 assert(index <= ParallelGCThreads, "out of range manager_array access");
190 return _manager_array[index];
191}
192
193bool ParCompactionManager::marking_stacks_empty() const {
194 return _marking_stack.is_empty() && _objarray_stack.is_empty();
195}
196
197#endif // SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
198