/
psCompactionManager.hpp
206 lines (163 loc) · 7.4 KB
/
psCompactionManager.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/*
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
#define SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
#include "gc/parallel/psParallelCompact.hpp"
#include "gc/shared/taskqueue.hpp"
#include "memory/allocation.hpp"
#include "utilities/stack.hpp"
class MutableSpace;
class PSOldGen;
class ParCompactionManager;
class ObjectStartArray;
class ParallelCompactData;
class ParMarkBitMap;
class ParCompactionManager : public CHeapObj<mtGC> {
friend class ParMarkBitMap;
friend class PSParallelCompact;
friend class CompactionWithStealingTask;
friend class UpdateAndFillClosure;
friend class RefProcTaskExecutor;
friend class PCRefProcTask;
friend class MarkFromRootsTask;
friend class UpdateDensePrefixAndCompactionTask;
private:
typedef GenericTaskQueue<oop, mtGC> OopTaskQueue;
typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet;
// 32-bit: 4K * 8 = 32KiB; 64-bit: 8K * 16 = 128KiB
#define QUEUE_SIZE (1 << NOT_LP64(12) LP64_ONLY(13))
typedef OverflowTaskQueue<ObjArrayTask, mtGC, QUEUE_SIZE> ObjArrayTaskQueue;
typedef GenericTaskQueueSet<ObjArrayTaskQueue, mtGC> ObjArrayTaskQueueSet;
#undef QUEUE_SIZE
typedef OverflowTaskQueue<size_t, mtGC> RegionTaskQueue;
typedef GenericTaskQueueSet<RegionTaskQueue, mtGC> RegionTaskQueueSet;
static ParCompactionManager** _manager_array;
static OopTaskQueueSet* _oop_task_queues;
static ObjArrayTaskQueueSet* _objarray_task_queues;
static ObjectStartArray* _start_array;
static RegionTaskQueueSet* _region_task_queues;
static PSOldGen* _old_gen;
OverflowTaskQueue<oop, mtGC> _marking_stack;
ObjArrayTaskQueue _objarray_stack;
size_t _next_shadow_region;
// Is there a way to reuse the _marking_stack for the
// saving empty regions? For now just create a different
// type of TaskQueue.
RegionTaskQueue _region_stack;
static ParMarkBitMap* _mark_bitmap;
// Contains currently free shadow regions. We use it in
// a LIFO fashion for better data locality and utilization.
static GrowableArray<size_t>* _shadow_region_array;
// Provides mutual exclusive access of _shadow_region_array.
// See pop/push_shadow_region_mt_safe() below
static Monitor* _shadow_region_monitor;
HeapWord* _last_query_beg;
oop _last_query_obj;
size_t _last_query_ret;
static PSOldGen* old_gen() { return _old_gen; }
static ObjectStartArray* start_array() { return _start_array; }
static OopTaskQueueSet* oop_task_queues() { return _oop_task_queues; }
static void initialize(ParMarkBitMap* mbm);
protected:
// Array of task queues. Needed by the task terminator.
static RegionTaskQueueSet* region_task_queues() { return _region_task_queues; }
OverflowTaskQueue<oop, mtGC>* marking_stack() { return &_marking_stack; }
// Pushes onto the marking stack. If the marking stack is full,
// pushes onto the overflow stack.
void stack_push(oop obj);
// Do not implement an equivalent stack_pop. Deal with the
// marking stack and overflow stack directly.
public:
static const size_t InvalidShadow = ~0;
static size_t pop_shadow_region_mt_safe(PSParallelCompact::RegionData* region_ptr);
static void push_shadow_region_mt_safe(size_t shadow_region);
static void push_shadow_region(size_t shadow_region);
static void remove_all_shadow_regions();
inline size_t next_shadow_region() { return _next_shadow_region; }
inline void set_next_shadow_region(size_t record) { _next_shadow_region = record; }
inline size_t move_next_shadow_region_by(size_t workers) {
_next_shadow_region += workers;
return next_shadow_region();
}
void reset_bitmap_query_cache() {
_last_query_beg = NULL;
_last_query_obj = NULL;
_last_query_ret = 0;
}
// Bitmap query support, cache last query and result
HeapWord* last_query_begin() { return _last_query_beg; }
oop last_query_object() { return _last_query_obj; }
size_t last_query_return() { return _last_query_ret; }
void set_last_query_begin(HeapWord *new_beg) { _last_query_beg = new_beg; }
void set_last_query_object(oop new_obj) { _last_query_obj = new_obj; }
void set_last_query_return(size_t new_ret) { _last_query_ret = new_ret; }
static void reset_all_bitmap_query_caches();
RegionTaskQueue* region_stack() { return &_region_stack; }
static ParCompactionManager* get_vmthread_cm() { return _manager_array[ParallelGCThreads]; }
ParCompactionManager();
// Pushes onto the region stack at the given index. If the
// region stack is full,
// pushes onto the region overflow stack.
static void verify_region_list_empty(uint stack_index);
ParMarkBitMap* mark_bitmap() { return _mark_bitmap; }
// void drain_stacks();
bool should_update();
bool should_copy();
// Save for later processing. Must not fail.
inline void push(oop obj);
inline void push_objarray(oop objarray, size_t index);
inline void push_region(size_t index);
// Check mark and maybe push on marking stack.
template <typename T> inline void mark_and_push(T* p);
inline void follow_klass(Klass* klass);
void follow_class_loader(ClassLoaderData* klass);
// Access function for compaction managers
static ParCompactionManager* gc_thread_compaction_manager(uint index);
static bool steal(int queue_num, oop& t);
static bool steal_objarray(int queue_num, ObjArrayTask& t);
static bool steal(int queue_num, size_t& region);
// Process tasks remaining on any marking stack
void follow_marking_stacks();
inline bool marking_stacks_empty() const;
// Process tasks remaining on any stack
void drain_region_stacks();
void follow_contents(oop obj);
void follow_array(objArrayOop array, int index);
void update_contents(oop obj);
class FollowStackClosure: public VoidClosure {
private:
ParCompactionManager* _compaction_manager;
public:
FollowStackClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
virtual void do_void();
};
// Called after marking.
static void verify_all_marking_stack_empty() NOT_DEBUG_RETURN;
// Region staks hold regions in from-space; called after compaction.
static void verify_all_region_stack_empty() NOT_DEBUG_RETURN;
};
bool ParCompactionManager::marking_stacks_empty() const {
return _marking_stack.is_empty() && _objarray_stack.is_empty();
}
#endif // SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP