hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
changeset 360 21d113ecbf6a
parent 1 489c9b5090e2
child 670 ddf3e9583f2f
equal deleted inserted replaced
357:f4edb0d9f109 360:21d113ecbf6a
   180   uint queue_size;
   180   uint queue_size;
   181   if (depth_first()) {
   181   if (depth_first()) {
   182     claimed_stack_depth()->initialize();
   182     claimed_stack_depth()->initialize();
   183     queue_size = claimed_stack_depth()->max_elems();
   183     queue_size = claimed_stack_depth()->max_elems();
   184     // We want the overflow stack to be permanent
   184     // We want the overflow stack to be permanent
   185     _overflow_stack_depth = new (ResourceObj::C_HEAP) GrowableArray<oop*>(10, true);
   185     _overflow_stack_depth = new (ResourceObj::C_HEAP) GrowableArray<StarTask>(10, true);
   186     _overflow_stack_breadth = NULL;
   186     _overflow_stack_breadth = NULL;
   187   } else {
   187   } else {
   188     claimed_stack_breadth()->initialize();
   188     claimed_stack_breadth()->initialize();
   189     queue_size = claimed_stack_breadth()->max_elems();
   189     queue_size = claimed_stack_breadth()->max_elems();
   190     // We want the overflow stack to be permanent
   190     // We want the overflow stack to be permanent
   238   _total_steals = 0;
   238   _total_steals = 0;
   239   _masked_steals = 0;
   239   _masked_steals = 0;
   240 #endif // PS_PM_STATS
   240 #endif // PS_PM_STATS
   241 }
   241 }
   242 
   242 
       
   243 
   243 void PSPromotionManager::drain_stacks_depth(bool totally_drain) {
   244 void PSPromotionManager::drain_stacks_depth(bool totally_drain) {
   244   assert(depth_first(), "invariant");
   245   assert(depth_first(), "invariant");
   245   assert(overflow_stack_depth() != NULL, "invariant");
   246   assert(overflow_stack_depth() != NULL, "invariant");
   246   totally_drain = totally_drain || _totally_drain;
   247   totally_drain = totally_drain || _totally_drain;
   247 
   248 
   252   MutableSpace* old_space = heap->old_gen()->object_space();
   253   MutableSpace* old_space = heap->old_gen()->object_space();
   253   MutableSpace* perm_space = heap->perm_gen()->object_space();
   254   MutableSpace* perm_space = heap->perm_gen()->object_space();
   254 #endif /* ASSERT */
   255 #endif /* ASSERT */
   255 
   256 
   256   do {
   257   do {
   257     oop* p;
   258     StarTask p;
   258 
   259 
   259     // Drain overflow stack first, so other threads can steal from
   260     // Drain overflow stack first, so other threads can steal from
   260     // claimed stack while we work.
   261     // claimed stack while we work.
   261     while(!overflow_stack_depth()->is_empty()) {
   262     while(!overflow_stack_depth()->is_empty()) {
   262       p = overflow_stack_depth()->pop();
   263       // linux compiler wants different overloaded operator= in taskqueue to
   263       process_popped_location_depth(p);
   264       // assign to p that the other compilers don't like.
       
   265       StarTask ptr = overflow_stack_depth()->pop();
       
   266       process_popped_location_depth(ptr);
   264     }
   267     }
   265 
   268 
   266     if (totally_drain) {
   269     if (totally_drain) {
   267       while (claimed_stack_depth()->pop_local(p)) {
   270       while (claimed_stack_depth()->pop_local(p)) {
   268         process_popped_location_depth(p);
   271         process_popped_location_depth(p);
   363 // into smaller submethods, but we need to be careful not to hurt
   366 // into smaller submethods, but we need to be careful not to hurt
   364 // performance.
   367 // performance.
   365 //
   368 //
   366 
   369 
   367 oop PSPromotionManager::copy_to_survivor_space(oop o, bool depth_first) {
   370 oop PSPromotionManager::copy_to_survivor_space(oop o, bool depth_first) {
   368   assert(PSScavenge::should_scavenge(o), "Sanity");
   371   assert(PSScavenge::should_scavenge(&o), "Sanity");
   369 
   372 
   370   oop new_obj = NULL;
   373   oop new_obj = NULL;
   371 
   374 
   372   // NOTE! We must be very careful with any methods that access the mark
   375   // NOTE! We must be very careful with any methods that access the mark
   373   // in o. There may be multiple threads racing on it, and it may be forwarded
   376   // in o. There may be multiple threads racing on it, and it may be forwarded
   528 
   531 
   529 #ifdef DEBUG
   532 #ifdef DEBUG
   530   // This code must come after the CAS test, or it will print incorrect
   533   // This code must come after the CAS test, or it will print incorrect
   531   // information.
   534   // information.
   532   if (TraceScavenge) {
   535   if (TraceScavenge) {
   533     gclog_or_tty->print_cr("{%s %s 0x%x -> 0x%x (%d)}",
   536     gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (" SIZE_FORMAT ")}",
   534        PSScavenge::should_scavenge(new_obj) ? "copying" : "tenuring",
   537        PSScavenge::should_scavenge(&new_obj) ? "copying" : "tenuring",
   535        new_obj->blueprint()->internal_name(), o, new_obj, new_obj->size());
   538        new_obj->blueprint()->internal_name(), o, new_obj, new_obj->size());
   536 
       
   537   }
   539   }
   538 #endif
   540 #endif
   539 
   541 
   540   return new_obj;
   542   return new_obj;
       
   543 }
       
   544 
       
   545 template <class T> void PSPromotionManager::process_array_chunk_work(
       
   546                                                  oop obj,
       
   547                                                  int start, int end) {
       
   548   assert(start < end, "invariant");
       
   549   T* const base      = (T*)objArrayOop(obj)->base();
       
   550   T* p               = base + start;
       
   551   T* const chunk_end = base + end;
       
   552   while (p < chunk_end) {
       
   553     if (PSScavenge::should_scavenge(p)) {
       
   554       claim_or_forward_depth(p);
       
   555     }
       
   556     ++p;
       
   557   }
   541 }
   558 }
   542 
   559 
   543 void PSPromotionManager::process_array_chunk(oop old) {
   560 void PSPromotionManager::process_array_chunk(oop old) {
   544   assert(PSChunkLargeArrays, "invariant");
   561   assert(PSChunkLargeArrays, "invariant");
   545   assert(old->is_objArray(), "invariant");
   562   assert(old->is_objArray(), "invariant");
   567     start = 0;
   584     start = 0;
   568     int const actual_length = arrayOop(obj)->length();
   585     int const actual_length = arrayOop(obj)->length();
   569     arrayOop(old)->set_length(actual_length);
   586     arrayOop(old)->set_length(actual_length);
   570   }
   587   }
   571 
   588 
   572   assert(start < end, "invariant");
   589   if (UseCompressedOops) {
   573   oop* const base      = objArrayOop(obj)->base();
   590     process_array_chunk_work<narrowOop>(obj, start, end);
   574   oop* p               = base + start;
   591   } else {
   575   oop* const chunk_end = base + end;
   592     process_array_chunk_work<oop>(obj, start, end);
   576   while (p < chunk_end) {
       
   577     if (PSScavenge::should_scavenge(*p)) {
       
   578       claim_or_forward_depth(p);
       
   579     }
       
   580     ++p;
       
   581   }
   593   }
   582 }
   594 }
   583 
   595 
   584 oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
   596 oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) {
   585   assert(_old_gen_is_full || PromotionFailureALot, "Sanity");
   597   assert(_old_gen_is_full || PromotionFailureALot, "Sanity");