rev 9846 : [mq]: par-scav-patch
rev 9847 : 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
Summary: A large part of time in the parallel scavenge collector is spent finding out the amount of live words within memory ranges to find out where to move an object to. Try to incrementally calculate this value.
Reviewed-by: tschatzl, mgerdin
Contributed-by: ray alex <sky1young@gmail.com>
1 /*
2 * Copyright (c) 2005, 2015, 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_PSCOMPACTIONMANAGER_HPP
26 #define SHARE_VM_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
27
28 #include "gc/shared/taskqueue.hpp"
29 #include "memory/allocation.hpp"
30 #include "utilities/stack.hpp"
31
32 class MutableSpace;
33 class PSOldGen;
34 class ParCompactionManager;
35 class ObjectStartArray;
36 class ParallelCompactData;
37 class ParMarkBitMap;
38
39 class ParCompactionManager : public CHeapObj<mtGC> {
40 friend class ParallelTaskTerminator;
41 friend class ParMarkBitMap;
42 friend class PSParallelCompact;
43 friend class StealRegionCompactionTask;
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
75 private:
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 RegionTaskQueue** _region_list;
85 // Index in _region_list for current _region_stack.
86 uint _region_stack_index;
87
88 // Indexes of recycled region stacks/overflow stacks
89 // Stacks of regions to be compacted are embedded in the tasks doing
90 // the compaction. A thread that executes the task extracts the
91 // region stack and drains it. These threads keep these region
92 // stacks for use during compaction task stealing. If a thread
93 // gets a second draining task, it pushed its current region stack
94 // index into the array _recycled_stack_index and gets a new
95 // region stack from the task. A thread that is executing a
96 // compaction stealing task without ever having executing a
97 // draining task, will get a region stack from _recycled_stack_index.
98 //
99 // Array of indexes into the array of region stacks.
100 static uint* _recycled_stack_index;
101 // The index into _recycled_stack_index of the last region stack index
102 // pushed. If -1, there are no entries into _recycled_stack_index.
103 static int _recycled_top;
104 // The index into _recycled_stack_index of the last region stack index
105 // popped. If -1, there has not been any entry popped.
106 static int _recycled_bottom;
107
108 static ParMarkBitMap* _mark_bitmap;
109
110 Action _action;
111
112 static PSOldGen* old_gen() { return _old_gen; }
113 static ObjectStartArray* start_array() { return _start_array; }
114 static OopTaskQueueSet* stack_array() { return _stack_array; }
115
116 static void initialize(ParMarkBitMap* mbm);
117
118 protected:
119 // Array of tasks. Needed by the ParallelTaskTerminator.
120 static RegionTaskQueueSet* region_array() { return _region_array; }
121 OverflowTaskQueue<oop, mtGC>* marking_stack() { return &_marking_stack; }
122
123 // Pushes onto the marking stack. If the marking stack is full,
124 // pushes onto the overflow stack.
125 void stack_push(oop obj);
126 // Do not implement an equivalent stack_pop. Deal with the
127 // marking stack and overflow stack directly.
128
129 public:
130 Action action() { return _action; }
131 void set_action(Action v) { _action = v; }
132
133 RegionTaskQueue* region_stack() { return _region_stack; }
134 void set_region_stack(RegionTaskQueue* v) { _region_stack = v; }
135
136 inline static ParCompactionManager* manager_array(uint index);
137
138 inline static RegionTaskQueue* region_list(int index) {
139 return _region_list[index];
140 }
141
142 uint region_stack_index() { return _region_stack_index; }
143 void set_region_stack_index(uint v) { _region_stack_index = v; }
144
145 // Pop and push unique reusable stack index
146 static int pop_recycled_stack_index();
147 static void push_recycled_stack_index(uint v);
148 static void reset_recycled_stack_index() {
149 _recycled_bottom = _recycled_top = -1;
150 }
151
152 ParCompactionManager();
153 ~ParCompactionManager();
154
155 // Pushes onto the region stack at the given index. If the
156 // region stack is full,
157 // pushes onto the region overflow stack.
158 static void region_list_push(uint stack_index, size_t region_index);
159 static void verify_region_list_empty(uint stack_index);
160 ParMarkBitMap* mark_bitmap() { return _mark_bitmap; }
161
162 // void drain_stacks();
163
164 bool should_update();
165 bool should_copy();
166
167 // Save for later processing. Must not fail.
168 inline void push(oop obj);
169 inline void push_objarray(oop objarray, size_t index);
170 inline void push_region(size_t index);
171
172 // Check mark and maybe push on marking stack.
173 template <typename T> inline void mark_and_push(T* p);
174
175 inline void follow_klass(Klass* klass);
176
177 void follow_class_loader(ClassLoaderData* klass);
178
179 // Access function for compaction managers
180 static ParCompactionManager* gc_thread_compaction_manager(uint index);
181
182 static bool steal(int queue_num, int* seed, oop& t);
183 static bool steal_objarray(int queue_num, int* seed, ObjArrayTask& t);
184 static bool steal(int queue_num, int* seed, size_t& region);
185
186 // Process tasks remaining on any marking stack
187 void follow_marking_stacks();
188 inline bool marking_stacks_empty() const;
189
190 // Process tasks remaining on any stack
191 void drain_region_stacks();
192
193 void follow_contents(oop obj);
194 void follow_contents(objArrayOop array, int index);
195
196 void update_contents(oop obj);
197
198 class MarkAndPushClosure: public ExtendedOopClosure {
199 private:
200 ParCompactionManager* _compaction_manager;
201 public:
202 MarkAndPushClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
203
204 template <typename T> void do_oop_nv(T* p);
205 virtual void do_oop(oop* p);
206 virtual void do_oop(narrowOop* p);
207
208 // This closure provides its own oop verification code.
209 debug_only(virtual bool should_verify_oops() { return false; })
210 };
211
212 class FollowStackClosure: public VoidClosure {
213 private:
214 ParCompactionManager* _compaction_manager;
215 public:
216 FollowStackClosure(ParCompactionManager* cm) : _compaction_manager(cm) { }
217 virtual void do_void();
218 };
219
220 // The one and only place to start following the classes.
221 // Should only be applied to the ClassLoaderData klasses list.
222 class FollowKlassClosure : public KlassClosure {
223 private:
224 MarkAndPushClosure* _mark_and_push_closure;
225 public:
226 FollowKlassClosure(MarkAndPushClosure* mark_and_push_closure) :
227 _mark_and_push_closure(mark_and_push_closure) { }
228 void do_klass(Klass* klass);
229 };
230 };
231
232 inline ParCompactionManager* ParCompactionManager::manager_array(uint index) {
233 assert(_manager_array != NULL, "access of NULL manager_array");
234 assert(index <= ParallelGCThreads, "out of range manager_array access");
235 return _manager_array[index];
236 }
237
238 bool ParCompactionManager::marking_stacks_empty() const {
239 return _marking_stack.is_empty() && _objarray_stack.is_empty();
240 }
241
242 #endif // SHARE_VM_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP
--- EOF ---