hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
changeset 30150 d9c940aa42ef
parent 29798 451c73fdf690
child 30173 13cf7580b000
equal deleted inserted replaced
30149:c0f930abe5ed 30150:d9c940aa42ef
    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