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 #include "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
28 #include "gc_implementation/parallelScavenge/objectStartArray.hpp"
29 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
30 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
31 #include "gc_implementation/parallelScavenge/psCompactionManager.inline.hpp"
32 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
33 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
34 #include "oops/objArrayKlass.inline.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "runtime/atomic.inline.hpp"
37 #include "utilities/stack.inline.hpp"
38
39 PSOldGen* ParCompactionManager::_old_gen = NULL;
40 ParCompactionManager** ParCompactionManager::_manager_array = NULL;
41
42 RegionTaskQueue** ParCompactionManager::_region_list = NULL;
43
44 OopTaskQueueSet* ParCompactionManager::_stack_array = NULL;
45 ParCompactionManager::ObjArrayTaskQueueSet*
46 ParCompactionManager::_objarray_queues = NULL;
47 ObjectStartArray* ParCompactionManager::_start_array = NULL;
48 ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL;
49 RegionTaskQueueSet* ParCompactionManager::_region_array = NULL;
50
51 uint* ParCompactionManager::_recycled_stack_index = NULL;
52 int ParCompactionManager::_recycled_top = -1;
53 int ParCompactionManager::_recycled_bottom = -1;
155 assert(action() != NotValid, "Action is not set");
156 return (action() == ParCompactionManager::Copy) ||
157 (action() == ParCompactionManager::CopyAndUpdate) ||
158 (action() == ParCompactionManager::UpdateAndCopy);
159 }
160
161 void ParCompactionManager::region_list_push(uint list_index,
162 size_t region_index) {
163 region_list(list_index)->push(region_index);
164 }
165
166 void ParCompactionManager::verify_region_list_empty(uint list_index) {
167 assert(region_list(list_index)->is_empty(), "Not empty");
168 }
169
170 ParCompactionManager*
171 ParCompactionManager::gc_thread_compaction_manager(int index) {
172 assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range");
173 assert(_manager_array != NULL, "Sanity");
174 return _manager_array[index];
175 }
176
177 void ParCompactionManager::follow_marking_stacks() {
178 do {
179 // Drain the overflow stack first, to allow stealing from the marking stack.
180 oop obj;
181 while (marking_stack()->pop_overflow(obj)) {
182 follow_contents(obj);
183 }
184 while (marking_stack()->pop_local(obj)) {
185 follow_contents(obj);
186 }
187
188 // Process ObjArrays one at a time to avoid marking stack bloat.
189 ObjArrayTask task;
190 if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) {
191 follow_contents((objArrayOop)task.obj(), task.index());
192 }
193 } while (!marking_stacks_empty());
194
|
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 #include "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
28 #include "gc_implementation/parallelScavenge/objectStartArray.hpp"
29 #include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
30 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
31 #include "gc_implementation/parallelScavenge/psCompactionManager.inline.hpp"
32 #include "gc_implementation/parallelScavenge/psOldGen.hpp"
33 #include "gc_implementation/parallelScavenge/psParallelCompact.inline.hpp"
34 #include "memory/iterator.inline.hpp"
35 #include "oops/instanceKlass.inline.hpp"
36 #include "oops/instanceMirrorKlass.inline.hpp"
37 #include "oops/objArrayKlass.inline.hpp"
38 #include "oops/oop.inline.hpp"
39 #include "runtime/atomic.inline.hpp"
40 #include "utilities/stack.inline.hpp"
41
42 PSOldGen* ParCompactionManager::_old_gen = NULL;
43 ParCompactionManager** ParCompactionManager::_manager_array = NULL;
44
45 RegionTaskQueue** ParCompactionManager::_region_list = NULL;
46
47 OopTaskQueueSet* ParCompactionManager::_stack_array = NULL;
48 ParCompactionManager::ObjArrayTaskQueueSet*
49 ParCompactionManager::_objarray_queues = NULL;
50 ObjectStartArray* ParCompactionManager::_start_array = NULL;
51 ParMarkBitMap* ParCompactionManager::_mark_bitmap = NULL;
52 RegionTaskQueueSet* ParCompactionManager::_region_array = NULL;
53
54 uint* ParCompactionManager::_recycled_stack_index = NULL;
55 int ParCompactionManager::_recycled_top = -1;
56 int ParCompactionManager::_recycled_bottom = -1;
158 assert(action() != NotValid, "Action is not set");
159 return (action() == ParCompactionManager::Copy) ||
160 (action() == ParCompactionManager::CopyAndUpdate) ||
161 (action() == ParCompactionManager::UpdateAndCopy);
162 }
163
164 void ParCompactionManager::region_list_push(uint list_index,
165 size_t region_index) {
166 region_list(list_index)->push(region_index);
167 }
168
169 void ParCompactionManager::verify_region_list_empty(uint list_index) {
170 assert(region_list(list_index)->is_empty(), "Not empty");
171 }
172
173 ParCompactionManager*
174 ParCompactionManager::gc_thread_compaction_manager(int index) {
175 assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range");
176 assert(_manager_array != NULL, "Sanity");
177 return _manager_array[index];
178 }
179
180 void InstanceKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
181 assert(obj != NULL, "can't follow the content of NULL object");
182
183 PSParallelCompact::follow_klass(cm, obj->klass());
184 // Only mark the header and let the scan of the meta-data mark
185 // everything else.
186
187 PSParallelCompact::MarkAndPushClosure cl(cm);
188 InstanceKlass::oop_oop_iterate_oop_maps<true>(obj, &cl);
189 }
190
191 void InstanceMirrorKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
192 InstanceKlass::oop_pc_follow_contents(obj, cm);
193
194 // Follow the klass field in the mirror.
195 Klass* klass = java_lang_Class::as_Klass(obj);
196 if (klass != NULL) {
197 // An anonymous class doesn't have its own class loader, so the call
198 // to follow_klass will mark and push its java mirror instead of the
199 // class loader. When handling the java mirror for an anonymous class
200 // we need to make sure its class loader data is claimed, this is done
201 // by calling follow_class_loader explicitly. For non-anonymous classes
202 // the call to follow_class_loader is made when the class loader itself
203 // is handled.
204 if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
205 PSParallelCompact::follow_class_loader(cm, klass->class_loader_data());
206 } else {
207 PSParallelCompact::follow_klass(cm, klass);
208 }
209 } else {
210 // If klass is NULL then this a mirror for a primitive type.
211 // We don't have to follow them, since they are handled as strong
212 // roots in Universe::oops_do.
213 assert(java_lang_Class::is_primitive(obj), "Sanity check");
214 }
215
216 PSParallelCompact::MarkAndPushClosure cl(cm);
217 oop_oop_iterate_statics<true>(obj, &cl);
218 }
219
220 void InstanceClassLoaderKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
221 InstanceKlass::oop_pc_follow_contents(obj, cm);
222
223 ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
224 if (loader_data != NULL) {
225 PSParallelCompact::follow_class_loader(cm, loader_data);
226 }
227 }
228
229 template <class T>
230 static void oop_pc_follow_contents_specialized(InstanceRefKlass* klass, oop obj, ParCompactionManager* cm) {
231 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
232 T heap_oop = oopDesc::load_heap_oop(referent_addr);
233 debug_only(
234 if(TraceReferenceGC && PrintGCDetails) {
235 gclog_or_tty->print_cr("InstanceRefKlass::oop_pc_follow_contents " PTR_FORMAT, p2i(obj));
236 }
237 )
238 if (!oopDesc::is_null(heap_oop)) {
239 oop referent = oopDesc::decode_heap_oop_not_null(heap_oop);
240 if (PSParallelCompact::mark_bitmap()->is_unmarked(referent) &&
241 PSParallelCompact::ref_processor()->discover_reference(obj, klass->reference_type())) {
242 // reference already enqueued, referent will be traversed later
243 klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
244 debug_only(
245 if(TraceReferenceGC && PrintGCDetails) {
246 gclog_or_tty->print_cr(" Non NULL enqueued " PTR_FORMAT, p2i(obj));
247 }
248 )
249 return;
250 } else {
251 // treat referent as normal oop
252 debug_only(
253 if(TraceReferenceGC && PrintGCDetails) {
254 gclog_or_tty->print_cr(" Non NULL normal " PTR_FORMAT, p2i(obj));
255 }
256 )
257 PSParallelCompact::mark_and_push(cm, referent_addr);
258 }
259 }
260 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
261 if (ReferenceProcessor::pending_list_uses_discovered_field()) {
262 // Treat discovered as normal oop, if ref is not "active",
263 // i.e. if next is non-NULL.
264 T next_oop = oopDesc::load_heap_oop(next_addr);
265 if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active"
266 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj);
267 debug_only(
268 if(TraceReferenceGC && PrintGCDetails) {
269 gclog_or_tty->print_cr(" Process discovered as normal "
270 PTR_FORMAT, p2i(discovered_addr));
271 }
272 )
273 PSParallelCompact::mark_and_push(cm, discovered_addr);
274 }
275 } else {
276 #ifdef ASSERT
277 // In the case of older JDKs which do not use the discovered
278 // field for the pending list, an inactive ref (next != NULL)
279 // must always have a NULL discovered field.
280 T next = oopDesc::load_heap_oop(next_addr);
281 oop discovered = java_lang_ref_Reference::discovered(obj);
282 assert(oopDesc::is_null(next) || oopDesc::is_null(discovered),
283 err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field",
284 p2i(obj)));
285 #endif
286 }
287 PSParallelCompact::mark_and_push(cm, next_addr);
288 klass->InstanceKlass::oop_pc_follow_contents(obj, cm);
289 }
290
291
292 void InstanceRefKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
293 if (UseCompressedOops) {
294 oop_pc_follow_contents_specialized<narrowOop>(this, obj, cm);
295 } else {
296 oop_pc_follow_contents_specialized<oop>(this, obj, cm);
297 }
298 }
299
300 void ObjArrayKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
301 PSParallelCompact::follow_klass(cm, this);
302
303 if (UseCompressedOops) {
304 oop_pc_follow_contents_specialized<narrowOop>(this, obj, 0, cm);
305 } else {
306 oop_pc_follow_contents_specialized<oop>(this, obj, 0, cm);
307 }
308 }
309
310 void TypeArrayKlass::oop_pc_follow_contents(oop obj, ParCompactionManager* cm) {
311 assert(obj->is_typeArray(),"must be a type array");
312 // Performance tweak: We skip iterating over the klass pointer since we
313 // know that Universe::TypeArrayKlass never moves.
314 }
315
316 void ParCompactionManager::follow_marking_stacks() {
317 do {
318 // Drain the overflow stack first, to allow stealing from the marking stack.
319 oop obj;
320 while (marking_stack()->pop_overflow(obj)) {
321 follow_contents(obj);
322 }
323 while (marking_stack()->pop_local(obj)) {
324 follow_contents(obj);
325 }
326
327 // Process ObjArrays one at a time to avoid marking stack bloat.
328 ObjArrayTask task;
329 if (_objarray_stack.pop_overflow(task) || _objarray_stack.pop_local(task)) {
330 follow_contents((objArrayOop)task.obj(), task.index());
331 }
332 } while (!marking_stacks_empty());
333
|