src/share/vm/gc_implementation/parNew/parNewGeneration.cpp

Print this page




  52 #include "runtime/handles.inline.hpp"
  53 #include "runtime/java.hpp"
  54 #include "runtime/thread.inline.hpp"
  55 #include "utilities/copy.hpp"
  56 #include "utilities/globalDefinitions.hpp"
  57 #include "utilities/workgroup.hpp"
  58 
  59 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  60 
  61 #ifdef _MSC_VER
  62 #pragma warning( push )
  63 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
  64 #endif
  65 ParScanThreadState::ParScanThreadState(Space* to_space_,
  66                                        ParNewGeneration* gen_,
  67                                        Generation* old_gen_,
  68                                        int thread_num_,
  69                                        ObjToScanQueueSet* work_queue_set_,
  70                                        Stack<oop, mtGC>* overflow_stacks_,
  71                                        size_t desired_plab_sz_,

  72                                        ParallelTaskTerminator& term_) :
  73   _to_space(to_space_), _old_gen(old_gen_), _young_gen(gen_), _thread_num(thread_num_),
  74   _work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false),
  75   _overflow_stack(overflow_stacks_ ? overflow_stacks_ + thread_num_ : NULL),
  76   _ageTable(false), // false ==> not the global age table, no perf data.
  77   _to_space_alloc_buffer(desired_plab_sz_),

  78   _to_space_closure(gen_, this), _old_gen_closure(gen_, this),
  79   _to_space_root_closure(gen_, this), _old_gen_root_closure(gen_, this),
  80   _older_gen_closure(gen_, this),
  81   _evacuate_followers(this, &_to_space_closure, &_old_gen_closure,
  82                       &_to_space_root_closure, gen_, &_old_gen_root_closure,
  83                       work_queue_set_, &term_),
  84   _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this),
  85   _keep_alive_closure(&_scan_weak_ref_closure),
  86   _strong_roots_time(0.0), _term_time(0.0)
  87 {
  88   #if TASKQUEUE_STATS
  89   _term_attempts = 0;
  90   _overflow_refills = 0;
  91   _overflow_refill_objs = 0;
  92   #endif // TASKQUEUE_STATS
  93 
  94   _survivor_chunk_array =
  95     (ChunkArray*) old_gen()->get_data_recorder(thread_num());
  96   _hash_seed = 17;  // Might want to take time-based random value.
  97   _start = os::elapsedTime();


 205     assert(Universe::heap()->is_in_reserved(cur), "Should be in heap");
 206     assert(!old_gen()->is_in_reserved(cur), "Should be in young gen");
 207     assert(Universe::heap()->is_in_reserved(obj_to_push), "Should be in heap");
 208     if (should_be_partially_scanned(obj_to_push, cur)) {
 209       assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
 210       obj_to_push = cur;
 211     }
 212     bool ok = queue->push(obj_to_push);
 213     assert(ok, "Should have succeeded");
 214   }
 215   assert(young_gen()->overflow_list() == NULL, "Error");
 216   return num_take_elems > 0;  // was something transferred?
 217 }
 218 
 219 void ParScanThreadState::push_on_overflow_stack(oop p) {
 220   assert(ParGCUseLocalOverflow, "Else should not call");
 221   overflow_stack()->push(p);
 222   assert(young_gen()->overflow_list() == NULL, "Error");
 223 }
 224 
 225 HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) {
 226 
 227   // Otherwise, if the object is small enough, try to reallocate the
 228   // buffer.
 229   HeapWord* obj = NULL;
 230   if (!_to_space_full) {
 231     ParGCAllocBuffer* const plab = to_space_alloc_buffer();
 232     Space*            const sp   = to_space();
 233     if (word_sz * 100 <
 234         ParallelGCBufferWastePct * plab->word_sz()) {
 235       // Is small enough; abandon this buffer and start a new one.
 236       plab->retire(false, false);
 237       size_t buf_size = plab->word_sz();
 238       HeapWord* buf_space = sp->par_allocate(buf_size);
 239       if (buf_space == NULL) {
 240         const size_t min_bytes =
 241           ParGCAllocBuffer::min_size() << LogHeapWordSize;
 242         size_t free_bytes = sp->free();
 243         while(buf_space == NULL && free_bytes >= min_bytes) {
 244           buf_size = free_bytes >> LogHeapWordSize;
 245           assert(buf_size == (size_t)align_object_size(buf_size),
 246                  "Invariant");
 247           buf_space  = sp->par_allocate(buf_size);
 248           free_bytes = sp->free();
 249         }
 250       }
 251       if (buf_space != NULL) {
 252         plab->set_word_size(buf_size);
 253         plab->set_buf(buf_space);
 254         record_survivor_plab(buf_space, buf_size);

 255         obj = plab->allocate_aligned(word_sz, SurvivorAlignmentInBytes);
 256         // Note that we cannot compare buf_size < word_sz below
 257         // because of AlignmentReserve (see ParGCAllocBuffer::allocate()).
 258         assert(obj != NULL || plab->words_remaining() < word_sz,
 259                "Else should have been able to allocate");
 260         // It's conceivable that we may be able to use the
 261         // buffer we just grabbed for subsequent small requests
 262         // even if not for this one.
 263       } else {
 264         // We're used up.
 265         _to_space_full = true;
 266       }
 267 
 268     } else {
 269       // Too large; allocate the object individually.

 270       obj = sp->par_allocate(word_sz);
 271     }
 272   }
 273   return obj;
 274 }
 275 
 276 
 277 void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj,
 278                                                 size_t word_sz) {
 279   // Is the alloc in the current alloc buffer?
 280   if (to_space_alloc_buffer()->contains(obj)) {
 281     assert(to_space_alloc_buffer()->contains(obj + word_sz - 1),
 282            "Should contain whole object.");
 283     to_space_alloc_buffer()->undo_allocation(obj, word_sz);
 284   } else {
 285     CollectedHeap::fill_with_object(obj, word_sz);
 286   }
 287 }
 288 
 289 void ParScanThreadState::print_promotion_failure_size() {
 290   if (_promotion_failed_info.has_failed() && PrintPromotionFailure) {
 291     gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ",
 292                         _thread_num, _promotion_failed_info.first_size());
 293   }
 294 }
 295 
 296 class ParScanThreadStateSet: private ResourceArray {
 297 public:
 298   // Initializes states for the specified number of threads;
 299   ParScanThreadStateSet(int                     num_threads,
 300                         Space&                  to_space,
 301                         ParNewGeneration&       gen,
 302                         Generation&             old_gen,
 303                         ObjToScanQueueSet&      queue_set,
 304                         Stack<oop, mtGC>*       overflow_stacks_,
 305                         size_t                  desired_plab_sz,

 306                         ParallelTaskTerminator& term);
 307 
 308   ~ParScanThreadStateSet() { TASKQUEUE_STATS_ONLY(reset_stats()); }
 309 
 310   inline ParScanThreadState& thread_state(int i);
 311 
 312   void trace_promotion_failed(YoungGCTracer& gc_tracer);
 313   void reset(int active_workers, bool promotion_failed);
 314   void flush();
 315 
 316   #if TASKQUEUE_STATS
 317   static void
 318     print_termination_stats_hdr(outputStream* const st = gclog_or_tty);
 319   void print_termination_stats(outputStream* const st = gclog_or_tty);
 320   static void
 321     print_taskqueue_stats_hdr(outputStream* const st = gclog_or_tty);
 322   void print_taskqueue_stats(outputStream* const st = gclog_or_tty);
 323   void reset_stats();
 324   #endif // TASKQUEUE_STATS
 325 
 326 private:
 327   ParallelTaskTerminator& _term;
 328   ParNewGeneration&       _gen;
 329   Generation&             _next_gen;
 330  public:
 331   bool is_valid(int id) const { return id < length(); }
 332   ParallelTaskTerminator* terminator() { return &_term; }
 333 };
 334 
 335 
 336 ParScanThreadStateSet::ParScanThreadStateSet(
 337   int num_threads, Space& to_space, ParNewGeneration& gen,
 338   Generation& old_gen, ObjToScanQueueSet& queue_set,
 339   Stack<oop, mtGC>* overflow_stacks,
 340   size_t desired_plab_sz, ParallelTaskTerminator& term)

 341   : ResourceArray(sizeof(ParScanThreadState), num_threads),
 342     _gen(gen), _next_gen(old_gen), _term(term)
 343 {
 344   assert(num_threads > 0, "sanity check!");
 345   assert(ParGCUseLocalOverflow == (overflow_stacks != NULL),
 346          "overflow_stack allocation mismatch");
 347   // Initialize states.
 348   for (int i = 0; i < num_threads; ++i) {
 349     new ((ParScanThreadState*)_data + i)
 350         ParScanThreadState(&to_space, &gen, &old_gen, i, &queue_set,
 351                            overflow_stacks, desired_plab_sz, term);
 352   }
 353 }
 354 
 355 inline ParScanThreadState& ParScanThreadStateSet::thread_state(int i)
 356 {
 357   assert(i >= 0 && i < length(), "sanity check!");
 358   return ((ParScanThreadState*)_data)[i];
 359 }
 360 
 361 void ParScanThreadStateSet::trace_promotion_failed(YoungGCTracer& gc_tracer) {
 362   for (int i = 0; i < length(); ++i) {
 363     if (thread_state(i).promotion_failed()) {
 364       gc_tracer.report_promotion_failed(thread_state(i).promotion_failed_info());
 365       thread_state(i).promotion_failed_info().reset();
 366     }
 367   }
 368 }
 369 
 370 void ParScanThreadStateSet::reset(int active_threads, bool promotion_failed)
 371 {


 963   // Capture heap used before collection (for printing).
 964   size_t gch_prev_used = gch->used();
 965 
 966   SpecializationStats::clear();
 967 
 968   age_table()->clear();
 969   to()->clear(SpaceDecorator::Mangle);
 970 
 971   gch->save_marks();
 972   assert(workers != NULL, "Need parallel worker threads.");
 973   int n_workers = active_workers;
 974 
 975   // Set the correct parallelism (number of queues) in the reference processor
 976   ref_processor()->set_active_mt_degree(n_workers);
 977 
 978   // Always set the terminator for the active number of workers
 979   // because only those workers go through the termination protocol.
 980   ParallelTaskTerminator _term(n_workers, task_queues());
 981   ParScanThreadStateSet thread_state_set(workers->active_workers(),
 982                                          *to(), *this, *_next_gen, *task_queues(),
 983                                          _overflow_stacks, desired_plab_sz(), _term);
 984 
 985   ParNewGenTask tsk(this, _next_gen, reserved().end(), &thread_state_set);
 986   gch->set_par_threads(n_workers);
 987   gch->rem_set()->prepare_for_younger_refs_iterate(true);
 988   // It turns out that even when we're using 1 thread, doing the work in a
 989   // separate thread causes wide variance in run times.  We can't help this
 990   // in the multi-threaded case, but we special-case n=1 here to get
 991   // repeatable measurements of the 1-thread overhead of the parallel code.
 992   if (n_workers > 1) {
 993     GenCollectedHeap::StrongRootsScope srs(gch);
 994     workers->run_task(&tsk);
 995   } else {
 996     GenCollectedHeap::StrongRootsScope srs(gch);
 997     tsk.work(0);
 998   }
 999   thread_state_set.reset(0 /* Bad value in debug if not reset */,
1000                          promotion_failed());
1001 
1002   // Process (weak) reference objects found during scavenge.
1003   ReferenceProcessor* rp = ref_processor();


1163         ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
1164   // In the sequential version, this assert also says that the object is
1165   // not forwarded.  That might not be the case here.  It is the case that
1166   // the caller observed it to be not forwarded at some time in the past.
1167   assert(is_in_reserved(old), "shouldn't be scavenging this oop");
1168 
1169   // The sequential code read "old->age()" below.  That doesn't work here,
1170   // since the age is in the mark word, and that might be overwritten with
1171   // a forwarding pointer by a parallel thread.  So we must save the mark
1172   // word in a local and then analyze it.
1173   oopDesc dummyOld;
1174   dummyOld.set_mark(m);
1175   assert(!dummyOld.is_forwarded(),
1176          "should not be called with forwarding pointer mark word.");
1177 
1178   oop new_obj = NULL;
1179   oop forward_ptr;
1180 
1181   // Try allocating obj in to-space (unless too old)
1182   if (dummyOld.age() < tenuring_threshold()) {
1183     new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
1184     if (new_obj == NULL) {
1185       set_survivor_overflow(true);
1186     }
1187   }
1188 
1189   if (new_obj == NULL) {
1190     // Either to-space is full or we decided to promote
1191     // try allocating obj tenured
1192 
1193     // Attempt to install a null forwarding pointer (atomically),
1194     // to claim the right to install the real forwarding pointer.
1195     forward_ptr = old->forward_to_atomic(ClaimedForwardPtr);
1196     if (forward_ptr != NULL) {
1197       // someone else beat us to it.
1198         return real_forwardee(old);
1199     }
1200 
1201     new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
1202                                        old, m, sz);
1203 


1290   // In the sequential version, this assert also says that the object is
1291   // not forwarded.  That might not be the case here.  It is the case that
1292   // the caller observed it to be not forwarded at some time in the past.
1293   assert(is_in_reserved(old), "shouldn't be scavenging this oop");
1294 
1295   // The sequential code read "old->age()" below.  That doesn't work here,
1296   // since the age is in the mark word, and that might be overwritten with
1297   // a forwarding pointer by a parallel thread.  So we must save the mark
1298   // word here, install it in a local oopDesc, and then analyze it.
1299   oopDesc dummyOld;
1300   dummyOld.set_mark(m);
1301   assert(!dummyOld.is_forwarded(),
1302          "should not be called with forwarding pointer mark word.");
1303 
1304   bool failed_to_promote = false;
1305   oop new_obj = NULL;
1306   oop forward_ptr;
1307 
1308   // Try allocating obj in to-space (unless too old)
1309   if (dummyOld.age() < tenuring_threshold()) {
1310     new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
1311     if (new_obj == NULL) {
1312       set_survivor_overflow(true);
1313     }
1314   }
1315 
1316   if (new_obj == NULL) {
1317     // Either to-space is full or we decided to promote
1318     // try allocating obj tenured
1319     new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
1320                                        old, m, sz);
1321 
1322     if (new_obj == NULL) {
1323       // promotion failed, forward to self
1324       forward_ptr = old->forward_to_atomic(old);
1325       new_obj = old;
1326 
1327       if (forward_ptr != NULL) {
1328         return forward_ptr;   // someone else succeeded
1329       }
1330 




  52 #include "runtime/handles.inline.hpp"
  53 #include "runtime/java.hpp"
  54 #include "runtime/thread.inline.hpp"
  55 #include "utilities/copy.hpp"
  56 #include "utilities/globalDefinitions.hpp"
  57 #include "utilities/workgroup.hpp"
  58 
  59 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
  60 
  61 #ifdef _MSC_VER
  62 #pragma warning( push )
  63 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
  64 #endif
  65 ParScanThreadState::ParScanThreadState(Space* to_space_,
  66                                        ParNewGeneration* gen_,
  67                                        Generation* old_gen_,
  68                                        int thread_num_,
  69                                        ObjToScanQueueSet* work_queue_set_,
  70                                        Stack<oop, mtGC>* overflow_stacks_,
  71                                        size_t desired_plab_sz_,
  72                                        ParNewTracer* gc_tracer,
  73                                        ParallelTaskTerminator& term_) :
  74   _to_space(to_space_), _old_gen(old_gen_), _young_gen(gen_), _thread_num(thread_num_),
  75   _work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false),
  76   _overflow_stack(overflow_stacks_ ? overflow_stacks_ + thread_num_ : NULL),
  77   _ageTable(false), // false ==> not the global age table, no perf data.
  78   _to_space_alloc_buffer(desired_plab_sz_),
  79   _gc_tracer(gc_tracer),
  80   _to_space_closure(gen_, this), _old_gen_closure(gen_, this),
  81   _to_space_root_closure(gen_, this), _old_gen_root_closure(gen_, this),
  82   _older_gen_closure(gen_, this),
  83   _evacuate_followers(this, &_to_space_closure, &_old_gen_closure,
  84                       &_to_space_root_closure, gen_, &_old_gen_root_closure,
  85                       work_queue_set_, &term_),
  86   _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this),
  87   _keep_alive_closure(&_scan_weak_ref_closure),
  88   _strong_roots_time(0.0), _term_time(0.0)
  89 {
  90   #if TASKQUEUE_STATS
  91   _term_attempts = 0;
  92   _overflow_refills = 0;
  93   _overflow_refill_objs = 0;
  94   #endif // TASKQUEUE_STATS
  95 
  96   _survivor_chunk_array =
  97     (ChunkArray*) old_gen()->get_data_recorder(thread_num());
  98   _hash_seed = 17;  // Might want to take time-based random value.
  99   _start = os::elapsedTime();


 207     assert(Universe::heap()->is_in_reserved(cur), "Should be in heap");
 208     assert(!old_gen()->is_in_reserved(cur), "Should be in young gen");
 209     assert(Universe::heap()->is_in_reserved(obj_to_push), "Should be in heap");
 210     if (should_be_partially_scanned(obj_to_push, cur)) {
 211       assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
 212       obj_to_push = cur;
 213     }
 214     bool ok = queue->push(obj_to_push);
 215     assert(ok, "Should have succeeded");
 216   }
 217   assert(young_gen()->overflow_list() == NULL, "Error");
 218   return num_take_elems > 0;  // was something transferred?
 219 }
 220 
 221 void ParScanThreadState::push_on_overflow_stack(oop p) {
 222   assert(ParGCUseLocalOverflow, "Else should not call");
 223   overflow_stack()->push(p);
 224   assert(young_gen()->overflow_list() == NULL, "Error");
 225 }
 226 
 227 HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz, oop const old, uint age) {
 228 
 229   // Otherwise, if the object is small enough, try to reallocate the
 230   // buffer.
 231   HeapWord* obj = NULL;
 232   if (!_to_space_full) {
 233     ParGCAllocBuffer* const plab = to_space_alloc_buffer();
 234     Space*            const sp   = to_space();
 235     if (word_sz * 100 <
 236         ParallelGCBufferWastePct * plab->word_sz()) {
 237       // Is small enough; abandon this buffer and start a new one.
 238       plab->retire(false, false);
 239       size_t buf_size = plab->word_sz();
 240       HeapWord* buf_space = sp->par_allocate(buf_size);
 241       if (buf_space == NULL) {
 242         const size_t min_bytes =
 243           ParGCAllocBuffer::min_size() << LogHeapWordSize;
 244         size_t free_bytes = sp->free();
 245         while(buf_space == NULL && free_bytes >= min_bytes) {
 246           buf_size = free_bytes >> LogHeapWordSize;
 247           assert(buf_size == (size_t)align_object_size(buf_size),
 248                  "Invariant");
 249           buf_space  = sp->par_allocate(buf_size);
 250           free_bytes = sp->free();
 251         }
 252       }
 253       if (buf_space != NULL) {
 254         plab->set_word_size(buf_size);
 255         plab->set_buf(buf_space);
 256         record_survivor_plab(buf_space, buf_size);
 257         gc_tracer()->report_promotion_to_new_plab(old, age, false, buf_size);
 258         obj = plab->allocate_aligned(word_sz, SurvivorAlignmentInBytes);
 259         // Note that we cannot compare buf_size < word_sz below
 260         // because of AlignmentReserve (see ParGCAllocBuffer::allocate()).
 261         assert(obj != NULL || plab->words_remaining() < word_sz,
 262                "Else should have been able to allocate");
 263         // It's conceivable that we may be able to use the
 264         // buffer we just grabbed for subsequent small requests
 265         // even if not for this one.
 266       } else {
 267         // We're used up.
 268         _to_space_full = true;
 269       }
 270 
 271     } else {
 272       // Too large; allocate the object individually.
 273       gc_tracer()->report_promotion_to_new_plab(old, age, false, old->size());
 274       obj = sp->par_allocate(word_sz);
 275     }
 276   }
 277   return obj;
 278 }
 279 
 280 
 281 void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj,
 282                                                 size_t word_sz) {
 283   // Is the alloc in the current alloc buffer?
 284   if (to_space_alloc_buffer()->contains(obj)) {
 285     assert(to_space_alloc_buffer()->contains(obj + word_sz - 1),
 286            "Should contain whole object.");
 287     to_space_alloc_buffer()->undo_allocation(obj, word_sz);
 288   } else {
 289     CollectedHeap::fill_with_object(obj, word_sz);
 290   }
 291 }
 292 
 293 void ParScanThreadState::print_promotion_failure_size() {
 294   if (_promotion_failed_info.has_failed() && PrintPromotionFailure) {
 295     gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ",
 296                         _thread_num, _promotion_failed_info.first_size());
 297   }
 298 }
 299 
 300 class ParScanThreadStateSet: private ResourceArray {
 301 public:
 302   // Initializes states for the specified number of threads;
 303   ParScanThreadStateSet(int                     num_threads,
 304                         Space&                  to_space,
 305                         ParNewGeneration&       gen,
 306                         Generation&             old_gen,
 307                         ObjToScanQueueSet&      queue_set,
 308                         Stack<oop, mtGC>*       overflow_stacks_,
 309                         size_t                  desired_plab_sz,
 310                         ParNewTracer*           gc_tracer,
 311                         ParallelTaskTerminator& term);
 312 
 313   ~ParScanThreadStateSet() { TASKQUEUE_STATS_ONLY(reset_stats()); }
 314 
 315   inline ParScanThreadState& thread_state(int i);
 316 
 317   void trace_promotion_failed(YoungGCTracer& gc_tracer);
 318   void reset(int active_workers, bool promotion_failed);
 319   void flush();
 320 
 321   #if TASKQUEUE_STATS
 322   static void
 323     print_termination_stats_hdr(outputStream* const st = gclog_or_tty);
 324   void print_termination_stats(outputStream* const st = gclog_or_tty);
 325   static void
 326     print_taskqueue_stats_hdr(outputStream* const st = gclog_or_tty);
 327   void print_taskqueue_stats(outputStream* const st = gclog_or_tty);
 328   void reset_stats();
 329   #endif // TASKQUEUE_STATS
 330 
 331 private:
 332   ParallelTaskTerminator& _term;
 333   ParNewGeneration&       _gen;
 334   Generation&             _next_gen;
 335  public:
 336   bool is_valid(int id) const { return id < length(); }
 337   ParallelTaskTerminator* terminator() { return &_term; }
 338 };
 339 
 340 
 341 ParScanThreadStateSet::ParScanThreadStateSet(
 342   int num_threads, Space& to_space, ParNewGeneration& gen,
 343   Generation& old_gen, ObjToScanQueueSet& queue_set,
 344   Stack<oop, mtGC>* overflow_stacks,
 345   size_t desired_plab_sz,
 346   ParNewTracer* gc_tracer, ParallelTaskTerminator& term)
 347   : ResourceArray(sizeof(ParScanThreadState), num_threads),
 348     _gen(gen), _next_gen(old_gen), _term(term)
 349 {
 350   assert(num_threads > 0, "sanity check!");
 351   assert(ParGCUseLocalOverflow == (overflow_stacks != NULL),
 352          "overflow_stack allocation mismatch");
 353   // Initialize states.
 354   for (int i = 0; i < num_threads; ++i) {
 355     new ((ParScanThreadState*)_data + i)
 356         ParScanThreadState(&to_space, &gen, &old_gen, i, &queue_set,
 357                            overflow_stacks, desired_plab_sz, gc_tracer, term);
 358   }
 359 }
 360 
 361 inline ParScanThreadState& ParScanThreadStateSet::thread_state(int i)
 362 {
 363   assert(i >= 0 && i < length(), "sanity check!");
 364   return ((ParScanThreadState*)_data)[i];
 365 }
 366 
 367 void ParScanThreadStateSet::trace_promotion_failed(YoungGCTracer& gc_tracer) {
 368   for (int i = 0; i < length(); ++i) {
 369     if (thread_state(i).promotion_failed()) {
 370       gc_tracer.report_promotion_failed(thread_state(i).promotion_failed_info());
 371       thread_state(i).promotion_failed_info().reset();
 372     }
 373   }
 374 }
 375 
 376 void ParScanThreadStateSet::reset(int active_threads, bool promotion_failed)
 377 {


 969   // Capture heap used before collection (for printing).
 970   size_t gch_prev_used = gch->used();
 971 
 972   SpecializationStats::clear();
 973 
 974   age_table()->clear();
 975   to()->clear(SpaceDecorator::Mangle);
 976 
 977   gch->save_marks();
 978   assert(workers != NULL, "Need parallel worker threads.");
 979   int n_workers = active_workers;
 980 
 981   // Set the correct parallelism (number of queues) in the reference processor
 982   ref_processor()->set_active_mt_degree(n_workers);
 983 
 984   // Always set the terminator for the active number of workers
 985   // because only those workers go through the termination protocol.
 986   ParallelTaskTerminator _term(n_workers, task_queues());
 987   ParScanThreadStateSet thread_state_set(workers->active_workers(),
 988                                          *to(), *this, *_next_gen, *task_queues(),
 989                                          _overflow_stacks, desired_plab_sz(), &gc_tracer, _term);
 990 
 991   ParNewGenTask tsk(this, _next_gen, reserved().end(), &thread_state_set);
 992   gch->set_par_threads(n_workers);
 993   gch->rem_set()->prepare_for_younger_refs_iterate(true);
 994   // It turns out that even when we're using 1 thread, doing the work in a
 995   // separate thread causes wide variance in run times.  We can't help this
 996   // in the multi-threaded case, but we special-case n=1 here to get
 997   // repeatable measurements of the 1-thread overhead of the parallel code.
 998   if (n_workers > 1) {
 999     GenCollectedHeap::StrongRootsScope srs(gch);
1000     workers->run_task(&tsk);
1001   } else {
1002     GenCollectedHeap::StrongRootsScope srs(gch);
1003     tsk.work(0);
1004   }
1005   thread_state_set.reset(0 /* Bad value in debug if not reset */,
1006                          promotion_failed());
1007 
1008   // Process (weak) reference objects found during scavenge.
1009   ReferenceProcessor* rp = ref_processor();


1169         ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
1170   // In the sequential version, this assert also says that the object is
1171   // not forwarded.  That might not be the case here.  It is the case that
1172   // the caller observed it to be not forwarded at some time in the past.
1173   assert(is_in_reserved(old), "shouldn't be scavenging this oop");
1174 
1175   // The sequential code read "old->age()" below.  That doesn't work here,
1176   // since the age is in the mark word, and that might be overwritten with
1177   // a forwarding pointer by a parallel thread.  So we must save the mark
1178   // word in a local and then analyze it.
1179   oopDesc dummyOld;
1180   dummyOld.set_mark(m);
1181   assert(!dummyOld.is_forwarded(),
1182          "should not be called with forwarding pointer mark word.");
1183 
1184   oop new_obj = NULL;
1185   oop forward_ptr;
1186 
1187   // Try allocating obj in to-space (unless too old)
1188   if (dummyOld.age() < tenuring_threshold()) {
1189     new_obj = (oop)par_scan_state->alloc_in_to_space(sz, old, dummyOld.age());
1190     if (new_obj == NULL) {
1191       set_survivor_overflow(true);
1192     }
1193   }
1194 
1195   if (new_obj == NULL) {
1196     // Either to-space is full or we decided to promote
1197     // try allocating obj tenured
1198 
1199     // Attempt to install a null forwarding pointer (atomically),
1200     // to claim the right to install the real forwarding pointer.
1201     forward_ptr = old->forward_to_atomic(ClaimedForwardPtr);
1202     if (forward_ptr != NULL) {
1203       // someone else beat us to it.
1204         return real_forwardee(old);
1205     }
1206 
1207     new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
1208                                        old, m, sz);
1209 


1296   // In the sequential version, this assert also says that the object is
1297   // not forwarded.  That might not be the case here.  It is the case that
1298   // the caller observed it to be not forwarded at some time in the past.
1299   assert(is_in_reserved(old), "shouldn't be scavenging this oop");
1300 
1301   // The sequential code read "old->age()" below.  That doesn't work here,
1302   // since the age is in the mark word, and that might be overwritten with
1303   // a forwarding pointer by a parallel thread.  So we must save the mark
1304   // word here, install it in a local oopDesc, and then analyze it.
1305   oopDesc dummyOld;
1306   dummyOld.set_mark(m);
1307   assert(!dummyOld.is_forwarded(),
1308          "should not be called with forwarding pointer mark word.");
1309 
1310   bool failed_to_promote = false;
1311   oop new_obj = NULL;
1312   oop forward_ptr;
1313 
1314   // Try allocating obj in to-space (unless too old)
1315   if (dummyOld.age() < tenuring_threshold()) {
1316     new_obj = (oop)par_scan_state->alloc_in_to_space(sz, old, dummyOld.age());
1317     if (new_obj == NULL) {
1318       set_survivor_overflow(true);
1319     }
1320   }
1321 
1322   if (new_obj == NULL) {
1323     // Either to-space is full or we decided to promote
1324     // try allocating obj tenured
1325     new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
1326                                        old, m, sz);
1327 
1328     if (new_obj == NULL) {
1329       // promotion failed, forward to self
1330       forward_ptr = old->forward_to_atomic(old);
1331       new_obj = old;
1332 
1333       if (forward_ptr != NULL) {
1334         return forward_ptr;   // someone else succeeded
1335       }
1336