30 #include "gc_implementation/shared/gcTrace.hpp" |
30 #include "gc_implementation/shared/gcTrace.hpp" |
31 #include "gc_implementation/shared/mutableSpace.hpp" |
31 #include "gc_implementation/shared/mutableSpace.hpp" |
32 #include "memory/allocation.inline.hpp" |
32 #include "memory/allocation.inline.hpp" |
33 #include "memory/memRegion.hpp" |
33 #include "memory/memRegion.hpp" |
34 #include "memory/padded.inline.hpp" |
34 #include "memory/padded.inline.hpp" |
|
35 #include "oops/instanceKlass.inline.hpp" |
|
36 #include "oops/instanceMirrorKlass.inline.hpp" |
|
37 #include "oops/objArrayKlass.inline.hpp" |
35 #include "oops/oop.inline.hpp" |
38 #include "oops/oop.inline.hpp" |
36 #include "utilities/stack.inline.hpp" |
39 #include "utilities/stack.inline.hpp" |
37 |
40 |
38 PaddedEnd<PSPromotionManager>* PSPromotionManager::_manager_array = NULL; |
41 PaddedEnd<PSPromotionManager>* PSPromotionManager::_manager_array = NULL; |
39 OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; |
42 OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; |
306 } else { |
309 } else { |
307 process_array_chunk_work<oop>(obj, start, end); |
310 process_array_chunk_work<oop>(obj, start, end); |
308 } |
311 } |
309 } |
312 } |
310 |
313 |
|
314 class PushContentsClosure : public ExtendedOopClosure { |
|
315 PSPromotionManager* _pm; |
|
316 public: |
|
317 PushContentsClosure(PSPromotionManager* pm) : _pm(pm) {} |
|
318 |
|
319 template <typename T> void do_oop_nv(T* p) { |
|
320 if (PSScavenge::should_scavenge(p)) { |
|
321 _pm->claim_or_forward_depth(p); |
|
322 } |
|
323 } |
|
324 |
|
325 virtual void do_oop(oop* p) { do_oop_nv(p); } |
|
326 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } |
|
327 |
|
328 // Don't use the oop verification code in the oop_oop_iterate framework. |
|
329 debug_only(virtual bool should_verify_oops() { return false; }) |
|
330 }; |
|
331 |
|
332 void InstanceKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) { |
|
333 PushContentsClosure cl(pm); |
|
334 oop_oop_iterate_oop_maps_reverse<true>(obj, &cl); |
|
335 } |
|
336 |
|
337 void InstanceMirrorKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) { |
|
338 // Note that we don't have to follow the mirror -> klass pointer, since all |
|
339 // klasses that are dirty will be scavenged when we iterate over the |
|
340 // ClassLoaderData objects. |
|
341 |
|
342 InstanceKlass::oop_ps_push_contents(obj, pm); |
|
343 |
|
344 PushContentsClosure cl(pm); |
|
345 oop_oop_iterate_statics<true>(obj, &cl); |
|
346 } |
|
347 |
|
348 void InstanceClassLoaderKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) { |
|
349 InstanceKlass::oop_ps_push_contents(obj, pm); |
|
350 |
|
351 // This is called by the young collector. It will already have taken care of |
|
352 // all class loader data. So, we don't have to follow the class loader -> |
|
353 // class loader data link. |
|
354 } |
|
355 |
|
356 template <class T> |
|
357 static void oop_ps_push_contents_specialized(oop obj, InstanceRefKlass *klass, PSPromotionManager* pm) { |
|
358 T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj); |
|
359 if (PSScavenge::should_scavenge(referent_addr)) { |
|
360 ReferenceProcessor* rp = PSScavenge::reference_processor(); |
|
361 if (rp->discover_reference(obj, klass->reference_type())) { |
|
362 // reference already enqueued, referent and next will be traversed later |
|
363 klass->InstanceKlass::oop_ps_push_contents(obj, pm); |
|
364 return; |
|
365 } else { |
|
366 // treat referent as normal oop |
|
367 pm->claim_or_forward_depth(referent_addr); |
|
368 } |
|
369 } |
|
370 // Treat discovered as normal oop, if ref is not "active", |
|
371 // i.e. if next is non-NULL. |
|
372 T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj); |
|
373 if (ReferenceProcessor::pending_list_uses_discovered_field()) { |
|
374 T next_oop = oopDesc::load_heap_oop(next_addr); |
|
375 if (!oopDesc::is_null(next_oop)) { // i.e. ref is not "active" |
|
376 T* discovered_addr = (T*)java_lang_ref_Reference::discovered_addr(obj); |
|
377 debug_only( |
|
378 if(TraceReferenceGC && PrintGCDetails) { |
|
379 gclog_or_tty->print_cr(" Process discovered as normal " |
|
380 PTR_FORMAT, p2i(discovered_addr)); |
|
381 } |
|
382 ) |
|
383 if (PSScavenge::should_scavenge(discovered_addr)) { |
|
384 pm->claim_or_forward_depth(discovered_addr); |
|
385 } |
|
386 } |
|
387 } else { |
|
388 #ifdef ASSERT |
|
389 // In the case of older JDKs which do not use the discovered |
|
390 // field for the pending list, an inactive ref (next != NULL) |
|
391 // must always have a NULL discovered field. |
|
392 oop next = oopDesc::load_decode_heap_oop(next_addr); |
|
393 oop discovered = java_lang_ref_Reference::discovered(obj); |
|
394 assert(oopDesc::is_null(next) || oopDesc::is_null(discovered), |
|
395 err_msg("Found an inactive reference " PTR_FORMAT " with a non-NULL discovered field", |
|
396 p2i(obj))); |
|
397 #endif |
|
398 } |
|
399 |
|
400 // Treat next as normal oop; next is a link in the reference queue. |
|
401 if (PSScavenge::should_scavenge(next_addr)) { |
|
402 pm->claim_or_forward_depth(next_addr); |
|
403 } |
|
404 klass->InstanceKlass::oop_ps_push_contents(obj, pm); |
|
405 } |
|
406 |
|
407 void InstanceRefKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) { |
|
408 if (UseCompressedOops) { |
|
409 oop_ps_push_contents_specialized<narrowOop>(obj, this, pm); |
|
410 } else { |
|
411 oop_ps_push_contents_specialized<oop>(obj, this, pm); |
|
412 } |
|
413 } |
|
414 |
|
415 void ObjArrayKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) { |
|
416 assert(obj->is_objArray(), "obj must be obj array"); |
|
417 PushContentsClosure cl(pm); |
|
418 oop_oop_iterate_elements<true>(objArrayOop(obj), &cl); |
|
419 } |
|
420 |
|
421 void TypeArrayKlass::oop_ps_push_contents(oop obj, PSPromotionManager* pm) { |
|
422 assert(obj->is_typeArray(),"must be a type array"); |
|
423 ShouldNotReachHere(); |
|
424 } |
|
425 |
311 oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) { |
426 oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) { |
312 assert(_old_gen_is_full || PromotionFailureALot, "Sanity"); |
427 assert(_old_gen_is_full || PromotionFailureALot, "Sanity"); |
313 |
428 |
314 // Attempt to CAS in the header. |
429 // Attempt to CAS in the header. |
315 // This tests if the header is still the same as when |
430 // This tests if the header is still the same as when |