hotspot/src/share/vm/gc/cms/parNewGeneration.cpp
changeset 38031 e0b822facc03
parent 36390 a2d991d1d628
child 38033 996ce936543f
equal deleted inserted replaced
38030:93f24e7b3c43 38031:e0b822facc03
   278     log_trace(gc, promotion)(" (%d: promotion failure size = " SIZE_FORMAT ") ",
   278     log_trace(gc, promotion)(" (%d: promotion failure size = " SIZE_FORMAT ") ",
   279                              _thread_num, _promotion_failed_info.first_size());
   279                              _thread_num, _promotion_failed_info.first_size());
   280   }
   280   }
   281 }
   281 }
   282 
   282 
   283 class ParScanThreadStateSet: private ResourceArray {
   283 class ParScanThreadStateSet: StackObj {
   284 public:
   284 public:
   285   // Initializes states for the specified number of threads;
   285   // Initializes states for the specified number of threads;
   286   ParScanThreadStateSet(int                     num_threads,
   286   ParScanThreadStateSet(int                     num_threads,
   287                         Space&                  to_space,
   287                         Space&                  to_space,
   288                         ParNewGeneration&       young_gen,
   288                         ParNewGeneration&       young_gen,
   313 
   313 
   314 private:
   314 private:
   315   ParallelTaskTerminator& _term;
   315   ParallelTaskTerminator& _term;
   316   ParNewGeneration&       _young_gen;
   316   ParNewGeneration&       _young_gen;
   317   Generation&             _old_gen;
   317   Generation&             _old_gen;
       
   318   ParScanThreadState*     _per_thread_states;
       
   319   const int               _num_threads;
   318  public:
   320  public:
   319   bool is_valid(int id) const { return id < length(); }
   321   bool is_valid(int id) const { return id < _num_threads; }
   320   ParallelTaskTerminator* terminator() { return &_term; }
   322   ParallelTaskTerminator* terminator() { return &_term; }
   321 };
   323 };
   322 
   324 
   323 ParScanThreadStateSet::ParScanThreadStateSet(int num_threads,
   325 ParScanThreadStateSet::ParScanThreadStateSet(int num_threads,
   324                                              Space& to_space,
   326                                              Space& to_space,
   327                                              ObjToScanQueueSet& queue_set,
   329                                              ObjToScanQueueSet& queue_set,
   328                                              Stack<oop, mtGC>* overflow_stacks,
   330                                              Stack<oop, mtGC>* overflow_stacks,
   329                                              PreservedMarksSet& preserved_marks_set,
   331                                              PreservedMarksSet& preserved_marks_set,
   330                                              size_t desired_plab_sz,
   332                                              size_t desired_plab_sz,
   331                                              ParallelTaskTerminator& term)
   333                                              ParallelTaskTerminator& term)
   332   : ResourceArray(sizeof(ParScanThreadState), num_threads),
   334   : _young_gen(young_gen),
   333     _young_gen(young_gen),
       
   334     _old_gen(old_gen),
   335     _old_gen(old_gen),
   335     _term(term)
   336     _term(term),
       
   337     _per_thread_states(NEW_RESOURCE_ARRAY(ParScanThreadState, num_threads)),
       
   338     _num_threads(num_threads)
   336 {
   339 {
   337   assert(num_threads > 0, "sanity check!");
   340   assert(num_threads > 0, "sanity check!");
   338   assert(ParGCUseLocalOverflow == (overflow_stacks != NULL),
   341   assert(ParGCUseLocalOverflow == (overflow_stacks != NULL),
   339          "overflow_stack allocation mismatch");
   342          "overflow_stack allocation mismatch");
   340   // Initialize states.
   343   // Initialize states.
   341   for (int i = 0; i < num_threads; ++i) {
   344   for (int i = 0; i < num_threads; ++i) {
   342     new ((ParScanThreadState*)_data + i)
   345     new(_per_thread_states + i)
   343         ParScanThreadState(&to_space, &young_gen, &old_gen, i, &queue_set,
   346       ParScanThreadState(&to_space, &young_gen, &old_gen, i, &queue_set,
   344                            overflow_stacks, preserved_marks_set.get(i),
   347                          overflow_stacks, preserved_marks_set.get(i),
   345                            desired_plab_sz, term);
   348                          desired_plab_sz, term);
   346   }
   349   }
   347 }
   350 }
   348 
   351 
   349 inline ParScanThreadState& ParScanThreadStateSet::thread_state(int i) {
   352 inline ParScanThreadState& ParScanThreadStateSet::thread_state(int i) {
   350   assert(i >= 0 && i < length(), "sanity check!");
   353   assert(i >= 0 && i < _num_threads, "sanity check!");
   351   return ((ParScanThreadState*)_data)[i];
   354   return _per_thread_states[i];
   352 }
   355 }
   353 
   356 
   354 void ParScanThreadStateSet::trace_promotion_failed(const YoungGCTracer* gc_tracer) {
   357 void ParScanThreadStateSet::trace_promotion_failed(const YoungGCTracer* gc_tracer) {
   355   for (int i = 0; i < length(); ++i) {
   358   for (int i = 0; i < _num_threads; ++i) {
   356     if (thread_state(i).promotion_failed()) {
   359     if (thread_state(i).promotion_failed()) {
   357       gc_tracer->report_promotion_failed(thread_state(i).promotion_failed_info());
   360       gc_tracer->report_promotion_failed(thread_state(i).promotion_failed_info());
   358       thread_state(i).promotion_failed_info().reset();
   361       thread_state(i).promotion_failed_info().reset();
   359     }
   362     }
   360   }
   363   }
   361 }
   364 }
   362 
   365 
   363 void ParScanThreadStateSet::reset(uint active_threads, bool promotion_failed) {
   366 void ParScanThreadStateSet::reset(uint active_threads, bool promotion_failed) {
   364   _term.reset_for_reuse(active_threads);
   367   _term.reset_for_reuse(active_threads);
   365   if (promotion_failed) {
   368   if (promotion_failed) {
   366     for (int i = 0; i < length(); ++i) {
   369     for (int i = 0; i < _num_threads; ++i) {
   367       thread_state(i).print_promotion_failure_size();
   370       thread_state(i).print_promotion_failure_size();
   368     }
   371     }
   369   }
   372   }
   370 }
   373 }
   371 
   374 
   376   _overflow_refills = 0;
   379   _overflow_refills = 0;
   377   _overflow_refill_objs = 0;
   380   _overflow_refill_objs = 0;
   378 }
   381 }
   379 
   382 
   380 void ParScanThreadStateSet::reset_stats() {
   383 void ParScanThreadStateSet::reset_stats() {
   381   for (int i = 0; i < length(); ++i) {
   384   for (int i = 0; i < _num_threads; ++i) {
   382     thread_state(i).reset_stats();
   385     thread_state(i).reset_stats();
   383   }
   386   }
   384 }
   387 }
   385 
   388 
   386 void ParScanThreadStateSet::print_termination_stats_hdr(outputStream* const st) {
   389 void ParScanThreadStateSet::print_termination_stats_hdr(outputStream* const st) {
   399   ResourceMark rm;
   402   ResourceMark rm;
   400   outputStream* st = log.debug_stream();
   403   outputStream* st = log.debug_stream();
   401 
   404 
   402   print_termination_stats_hdr(st);
   405   print_termination_stats_hdr(st);
   403 
   406 
   404   for (int i = 0; i < length(); ++i) {
   407   for (int i = 0; i < _num_threads; ++i) {
   405     const ParScanThreadState & pss = thread_state(i);
   408     const ParScanThreadState & pss = thread_state(i);
   406     const double elapsed_ms = pss.elapsed_time() * 1000.0;
   409     const double elapsed_ms = pss.elapsed_time() * 1000.0;
   407     const double s_roots_ms = pss.strong_roots_time() * 1000.0;
   410     const double s_roots_ms = pss.strong_roots_time() * 1000.0;
   408     const double term_ms = pss.term_time() * 1000.0;
   411     const double term_ms = pss.term_time() * 1000.0;
   409     st->print_cr("%3d %9.2f %9.2f %6.2f %9.2f %6.2f " SIZE_FORMAT_W(8),
   412     st->print_cr("%3d %9.2f %9.2f %6.2f %9.2f %6.2f " SIZE_FORMAT_W(8),
   427   ResourceMark rm;
   430   ResourceMark rm;
   428   outputStream* st = log.trace_stream();
   431   outputStream* st = log.trace_stream();
   429   print_taskqueue_stats_hdr(st);
   432   print_taskqueue_stats_hdr(st);
   430 
   433 
   431   TaskQueueStats totals;
   434   TaskQueueStats totals;
   432   for (int i = 0; i < length(); ++i) {
   435   for (int i = 0; i < _num_threads; ++i) {
   433     const ParScanThreadState & pss = thread_state(i);
   436     const ParScanThreadState & pss = thread_state(i);
   434     const TaskQueueStats & stats = pss.taskqueue_stats();
   437     const TaskQueueStats & stats = pss.taskqueue_stats();
   435     st->print("%3d ", i); stats.print(st); st->cr();
   438     st->print("%3d ", i); stats.print(st); st->cr();
   436     totals += stats;
   439     totals += stats;
   437 
   440 
   450 void ParScanThreadStateSet::flush() {
   453 void ParScanThreadStateSet::flush() {
   451   // Work in this loop should be kept as lightweight as
   454   // Work in this loop should be kept as lightweight as
   452   // possible since this might otherwise become a bottleneck
   455   // possible since this might otherwise become a bottleneck
   453   // to scaling. Should we add heavy-weight work into this
   456   // to scaling. Should we add heavy-weight work into this
   454   // loop, consider parallelizing the loop into the worker threads.
   457   // loop, consider parallelizing the loop into the worker threads.
   455   for (int i = 0; i < length(); ++i) {
   458   for (int i = 0; i < _num_threads; ++i) {
   456     ParScanThreadState& par_scan_state = thread_state(i);
   459     ParScanThreadState& par_scan_state = thread_state(i);
   457 
   460 
   458     // Flush stats related to To-space PLAB activity and
   461     // Flush stats related to To-space PLAB activity and
   459     // retire the last buffer.
   462     // retire the last buffer.
   460     par_scan_state.to_space_alloc_buffer()->flush_and_retire_stats(_young_gen.plab_stats());
   463     par_scan_state.to_space_alloc_buffer()->flush_and_retire_stats(_young_gen.plab_stats());