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) {
458 // Work in this loop should be kept as lightweight as
459 // possible since this might otherwise become a bottleneck
460 // to scaling. Should we add heavy-weight work into this
461 // loop, consider parallelizing the loop into the worker threads.
462 for (int i = 0; i < length(); ++i) {
463 ParScanThreadState& par_scan_state = thread_state(i);
464
465 // Flush stats related to To-space PLAB activity and
466 // retire the last buffer.
467 par_scan_state.to_space_alloc_buffer()->
468 flush_stats_and_retire(_gen.plab_stats(),
469 true /* end_of_gc */,
470 false /* retain */);
471
472 // Every thread has its own age table. We need to merge
473 // them all into one.
474 ageTable *local_table = par_scan_state.age_table();
475 _gen.age_table()->merge(local_table);
476
477 // Inform old gen that we're done.
478 _next_gen.par_promote_alloc_done(i);
479 _next_gen.par_oop_since_save_marks_iterate_done(i);
480 }
481
482 if (UseConcMarkSweepGC && ParallelGCThreads > 0) {
483 // We need to call this even when ResizeOldPLAB is disabled
484 // so as to avoid breaking some asserts. While we may be able
485 // to avoid this by reorganizing the code a bit, I am loathe
486 // to do that unless we find cases where ergo leads to bad
487 // performance.
488 CFLS_LAB::compute_desired_plab_size();
489 }
490 }
491
492 ParScanClosure::ParScanClosure(ParNewGeneration* g,
493 ParScanThreadState* par_scan_state) :
494 OopsInKlassOrGenClosure(g), _par_scan_state(par_scan_state), _g(g)
495 {
496 assert(_g->level() == 0, "Optimized for youngest generation");
497 _boundary = _g->reserved().end();
498 }
499
561
562 // if successful, goto Start.
563 continue;
564
565 // try global overflow list.
566 } else if (par_gen()->take_from_overflow_list(par_scan_state())) {
567 continue;
568 }
569
570 // Otherwise, offer termination.
571 par_scan_state()->start_term_time();
572 if (terminator()->offer_termination()) break;
573 par_scan_state()->end_term_time();
574 }
575 assert(par_gen()->_overflow_list == NULL && par_gen()->_num_par_pushes == 0,
576 "Broken overflow list?");
577 // Finish the last termination pause.
578 par_scan_state()->end_term_time();
579 }
580
581 ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* next_gen,
582 HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
583 AbstractGangTask("ParNewGeneration collection"),
584 _gen(gen), _next_gen(next_gen),
585 _young_old_boundary(young_old_boundary),
586 _state_set(state_set)
587 {}
588
589 // Reset the terminator for the given number of
590 // active threads.
591 void ParNewGenTask::set_for_termination(int active_workers) {
592 _state_set->reset(active_workers, _gen->promotion_failed());
593 // Should the heap be passed in? There's only 1 for now so
594 // grab it instead.
595 GenCollectedHeap* gch = GenCollectedHeap::heap();
596 gch->set_n_termination(active_workers);
597 }
598
599 void ParNewGenTask::work(uint worker_id) {
600 GenCollectedHeap* gch = GenCollectedHeap::heap();
601 // Since this is being done in a separate thread, need new resource
602 // and handle marks.
603 ResourceMark rm;
604 HandleMark hm;
605 // We would need multiple old-gen queues otherwise.
606 assert(gch->n_gens() == 2, "Par young collection currently only works with one older gen.");
607
608 Generation* old_gen = gch->next_gen(_gen);
609
610 ParScanThreadState& par_scan_state = _state_set->thread_state(worker_id);
611 assert(_state_set->is_valid(worker_id), "Should not have been called");
612
613 par_scan_state.set_young_old_boundary(_young_old_boundary);
614
615 KlassScanClosure klass_scan_closure(&par_scan_state.to_space_root_closure(),
616 gch->rem_set()->klass_rem_set());
617 CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure,
618 &par_scan_state.to_space_root_closure(),
619 false);
620
621 par_scan_state.start_strong_roots();
622 gch->gen_process_roots(_gen->level(),
623 true, // Process younger gens, if any,
624 // as strong roots.
625 false, // no scope; this is parallel code
626 SharedHeap::SO_ScavengeCodeCache,
627 GenCollectedHeap::StrongAndWeakRoots,
628 &par_scan_state.to_space_root_closure(),
751 ? obj->forwardee()
752 : _g->DefNewGeneration::copy_to_survivor_space(obj);
753 oopDesc::encode_store_heap_oop_not_null(p, new_obj);
754 }
755 if (_gc_barrier) {
756 // If p points to a younger generation, mark the card.
757 if ((HeapWord*)obj < _gen_boundary) {
758 _rs->write_ref_field_gc_par(p, obj);
759 }
760 }
761 }
762 }
763
764 void ScanClosureWithParBarrier::do_oop(oop* p) { ScanClosureWithParBarrier::do_oop_work(p); }
765 void ScanClosureWithParBarrier::do_oop(narrowOop* p) { ScanClosureWithParBarrier::do_oop_work(p); }
766
767 class ParNewRefProcTaskProxy: public AbstractGangTask {
768 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
769 public:
770 ParNewRefProcTaskProxy(ProcessTask& task, ParNewGeneration& gen,
771 Generation& next_gen,
772 HeapWord* young_old_boundary,
773 ParScanThreadStateSet& state_set);
774
775 private:
776 virtual void work(uint worker_id);
777 virtual void set_for_termination(int active_workers) {
778 _state_set.terminator()->reset_for_reuse(active_workers);
779 }
780 private:
781 ParNewGeneration& _gen;
782 ProcessTask& _task;
783 Generation& _next_gen;
784 HeapWord* _young_old_boundary;
785 ParScanThreadStateSet& _state_set;
786 };
787
788 ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(
789 ProcessTask& task, ParNewGeneration& gen,
790 Generation& next_gen,
791 HeapWord* young_old_boundary,
792 ParScanThreadStateSet& state_set)
793 : AbstractGangTask("ParNewGeneration parallel reference processing"),
794 _gen(gen),
795 _task(task),
796 _next_gen(next_gen),
797 _young_old_boundary(young_old_boundary),
798 _state_set(state_set)
799 {
800 }
801
802 void ParNewRefProcTaskProxy::work(uint worker_id)
803 {
804 ResourceMark rm;
805 HandleMark hm;
806 ParScanThreadState& par_scan_state = _state_set.thread_state(worker_id);
807 par_scan_state.set_young_old_boundary(_young_old_boundary);
808 _task.work(worker_id, par_scan_state.is_alive_closure(),
809 par_scan_state.keep_alive_closure(),
810 par_scan_state.evacuate_followers_closure());
811 }
812
813 class ParNewRefEnqueueTaskProxy: public AbstractGangTask {
814 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
815 EnqueueTask& _task;
816
882 }
883
884
885 // A Generation that does parallel young-gen collection.
886
887 bool ParNewGeneration::_avoid_promotion_undo = false;
888
889 void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) {
890 assert(_promo_failure_scan_stack.is_empty(), "post condition");
891 _promo_failure_scan_stack.clear(true); // Clear cached segments.
892
893 remove_forwarding_pointers();
894 if (PrintGCDetails) {
895 gclog_or_tty->print(" (promotion failed)");
896 }
897 // All the spaces are in play for mark-sweep.
898 swap_spaces(); // Make life simpler for CMS || rescan; see 6483690.
899 from()->set_next_compaction_space(to());
900 gch->set_incremental_collection_failed();
901 // Inform the next generation that a promotion failure occurred.
902 _next_gen->promotion_failure_occurred();
903
904 // Trace promotion failure in the parallel GC threads
905 thread_state_set.trace_promotion_failed(gc_tracer);
906 // Single threaded code may have reported promotion failure to the global state
907 if (_promotion_failed_info.has_failed()) {
908 gc_tracer.report_promotion_failed(_promotion_failed_info);
909 }
910 // Reset the PromotionFailureALot counters.
911 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
912 }
913
914 void ParNewGeneration::collect(bool full,
915 bool clear_all_soft_refs,
916 size_t size,
917 bool is_tlab) {
918 assert(full || size > 0, "otherwise we don't want to collect");
919
920 GenCollectedHeap* gch = GenCollectedHeap::heap();
921
922 _gc_timer->register_gc_start();
923
924 assert(gch->kind() == CollectedHeap::GenCollectedHeap,
925 "not a CMS generational heap");
926 AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
927 FlexibleWorkGang* workers = gch->workers();
928 assert(workers != NULL, "Need workgang for parallel work");
929 int active_workers =
930 AdaptiveSizePolicy::calc_active_workers(workers->total_workers(),
931 workers->active_workers(),
932 Threads::number_of_non_daemon_threads());
933 workers->set_active_workers(active_workers);
934 assert(gch->n_gens() == 2,
935 "Par collection currently only works with single older gen.");
936 _next_gen = gch->next_gen(this);
937 // Do we have to avoid promotion_undo?
938 if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) {
939 set_avoid_promotion_undo(true);
940 }
941
942 // If the next generation is too full to accommodate worst-case promotion
943 // from this generation, pass on collection; let the next generation
944 // do it.
945 if (!collection_attempt_is_safe()) {
946 gch->set_incremental_collection_failed(); // slight lie, in that we did not even attempt one
947 return;
948 }
949 assert(to()->is_empty(), "Else not collection_attempt_is_safe");
950
951 ParNewTracer gc_tracer;
952 gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
953 gch->trace_heap_before_gc(&gc_tracer);
954
955 init_assuming_no_promotion_failure();
956
962 GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, gc_tracer.gc_id());
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();
1004 IsAliveClosure is_alive(this);
1005 ScanWeakRefClosure scan_weak_ref(this);
1179 // Try allocating obj in to-space (unless too old)
1180 if (dummyOld.age() < tenuring_threshold()) {
1181 new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
1182 if (new_obj == NULL) {
1183 set_survivor_overflow(true);
1184 }
1185 }
1186
1187 if (new_obj == NULL) {
1188 // Either to-space is full or we decided to promote
1189 // try allocating obj tenured
1190
1191 // Attempt to install a null forwarding pointer (atomically),
1192 // to claim the right to install the real forwarding pointer.
1193 forward_ptr = old->forward_to_atomic(ClaimedForwardPtr);
1194 if (forward_ptr != NULL) {
1195 // someone else beat us to it.
1196 return real_forwardee(old);
1197 }
1198
1199 new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
1200 old, m, sz);
1201
1202 if (new_obj == NULL) {
1203 // promotion failed, forward to self
1204 _promotion_failed = true;
1205 new_obj = old;
1206
1207 preserve_mark_if_necessary(old, m);
1208 par_scan_state->register_promotion_failure(sz);
1209 }
1210
1211 old->forward_to(new_obj);
1212 forward_ptr = NULL;
1213 } else {
1214 // Is in to-space; do copying ourselves.
1215 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
1216 forward_ptr = old->forward_to_atomic(new_obj);
1217 // Restore the mark word copied above.
1218 new_obj->set_mark(m);
1219 // Increment age if obj still in new generation
1297 oopDesc dummyOld;
1298 dummyOld.set_mark(m);
1299 assert(!dummyOld.is_forwarded(),
1300 "should not be called with forwarding pointer mark word.");
1301
1302 bool failed_to_promote = false;
1303 oop new_obj = NULL;
1304 oop forward_ptr;
1305
1306 // Try allocating obj in to-space (unless too old)
1307 if (dummyOld.age() < tenuring_threshold()) {
1308 new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
1309 if (new_obj == NULL) {
1310 set_survivor_overflow(true);
1311 }
1312 }
1313
1314 if (new_obj == NULL) {
1315 // Either to-space is full or we decided to promote
1316 // try allocating obj tenured
1317 new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
1318 old, m, sz);
1319
1320 if (new_obj == NULL) {
1321 // promotion failed, forward to self
1322 forward_ptr = old->forward_to_atomic(old);
1323 new_obj = old;
1324
1325 if (forward_ptr != NULL) {
1326 return forward_ptr; // someone else succeeded
1327 }
1328
1329 _promotion_failed = true;
1330 failed_to_promote = true;
1331
1332 preserve_mark_if_necessary(old, m);
1333 par_scan_state->register_promotion_failure(sz);
1334 }
1335 } else {
1336 // Is in to-space; do copying ourselves.
1337 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
1378 simulate_overflow = true;
1379 }
1380 )
1381 if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
1382 // Add stats for overflow pushes.
1383 push_on_overflow_list(old, par_scan_state);
1384 TASKQUEUE_STATS_ONLY(par_scan_state->taskqueue_stats().record_overflow(0));
1385 }
1386
1387 return new_obj;
1388 }
1389
1390 // Oops. Someone beat us to it. Undo the allocation. Where did we
1391 // allocate it?
1392 if (is_in_reserved(new_obj)) {
1393 // Must be in to_space.
1394 assert(to()->is_in_reserved(new_obj), "Checking");
1395 par_scan_state->undo_alloc_in_to_space((HeapWord*)new_obj, sz);
1396 } else {
1397 assert(!_avoid_promotion_undo, "Should not be here if avoiding.");
1398 _next_gen->par_promote_alloc_undo(par_scan_state->thread_num(),
1399 (HeapWord*)new_obj, sz);
1400 }
1401
1402 return forward_ptr;
1403 }
1404
1405 #ifndef PRODUCT
1406 // It's OK to call this multi-threaded; the worst thing
1407 // that can happen is that we'll get a bunch of closely
1408 // spaced simulated overflows, but that's OK, in fact
1409 // probably good as it would exercise the overflow code
1410 // under contention.
1411 bool ParNewGeneration::should_simulate_overflow() {
1412 if (_overflow_counter-- <= 0) { // just being defensive
1413 _overflow_counter = ParGCWorkQueueOverflowInterval;
1414 return true;
1415 } else {
1416 return false;
1417 }
1418 }
|
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& _old_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), _old_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) {
458 // Work in this loop should be kept as lightweight as
459 // possible since this might otherwise become a bottleneck
460 // to scaling. Should we add heavy-weight work into this
461 // loop, consider parallelizing the loop into the worker threads.
462 for (int i = 0; i < length(); ++i) {
463 ParScanThreadState& par_scan_state = thread_state(i);
464
465 // Flush stats related to To-space PLAB activity and
466 // retire the last buffer.
467 par_scan_state.to_space_alloc_buffer()->
468 flush_stats_and_retire(_gen.plab_stats(),
469 true /* end_of_gc */,
470 false /* retain */);
471
472 // Every thread has its own age table. We need to merge
473 // them all into one.
474 ageTable *local_table = par_scan_state.age_table();
475 _gen.age_table()->merge(local_table);
476
477 // Inform old gen that we're done.
478 _old_gen.par_promote_alloc_done(i);
479 _old_gen.par_oop_since_save_marks_iterate_done(i);
480 }
481
482 if (UseConcMarkSweepGC && ParallelGCThreads > 0) {
483 // We need to call this even when ResizeOldPLAB is disabled
484 // so as to avoid breaking some asserts. While we may be able
485 // to avoid this by reorganizing the code a bit, I am loathe
486 // to do that unless we find cases where ergo leads to bad
487 // performance.
488 CFLS_LAB::compute_desired_plab_size();
489 }
490 }
491
492 ParScanClosure::ParScanClosure(ParNewGeneration* g,
493 ParScanThreadState* par_scan_state) :
494 OopsInKlassOrGenClosure(g), _par_scan_state(par_scan_state), _g(g)
495 {
496 assert(_g->level() == 0, "Optimized for youngest generation");
497 _boundary = _g->reserved().end();
498 }
499
561
562 // if successful, goto Start.
563 continue;
564
565 // try global overflow list.
566 } else if (par_gen()->take_from_overflow_list(par_scan_state())) {
567 continue;
568 }
569
570 // Otherwise, offer termination.
571 par_scan_state()->start_term_time();
572 if (terminator()->offer_termination()) break;
573 par_scan_state()->end_term_time();
574 }
575 assert(par_gen()->_overflow_list == NULL && par_gen()->_num_par_pushes == 0,
576 "Broken overflow list?");
577 // Finish the last termination pause.
578 par_scan_state()->end_term_time();
579 }
580
581 ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* old_gen,
582 HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
583 AbstractGangTask("ParNewGeneration collection"),
584 _gen(gen), _old_gen(old_gen),
585 _young_old_boundary(young_old_boundary),
586 _state_set(state_set)
587 {}
588
589 // Reset the terminator for the given number of
590 // active threads.
591 void ParNewGenTask::set_for_termination(int active_workers) {
592 _state_set->reset(active_workers, _gen->promotion_failed());
593 // Should the heap be passed in? There's only 1 for now so
594 // grab it instead.
595 GenCollectedHeap* gch = GenCollectedHeap::heap();
596 gch->set_n_termination(active_workers);
597 }
598
599 void ParNewGenTask::work(uint worker_id) {
600 GenCollectedHeap* gch = GenCollectedHeap::heap();
601 // Since this is being done in a separate thread, need new resource
602 // and handle marks.
603 ResourceMark rm;
604 HandleMark hm;
605 // We would need multiple old-gen queues otherwise.
606 assert(gch->n_gens() == 2, "Par young collection currently only works with one older gen.");
607
608 Generation* old_gen = gch->old_gen();
609
610 ParScanThreadState& par_scan_state = _state_set->thread_state(worker_id);
611 assert(_state_set->is_valid(worker_id), "Should not have been called");
612
613 par_scan_state.set_young_old_boundary(_young_old_boundary);
614
615 KlassScanClosure klass_scan_closure(&par_scan_state.to_space_root_closure(),
616 gch->rem_set()->klass_rem_set());
617 CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure,
618 &par_scan_state.to_space_root_closure(),
619 false);
620
621 par_scan_state.start_strong_roots();
622 gch->gen_process_roots(_gen->level(),
623 true, // Process younger gens, if any,
624 // as strong roots.
625 false, // no scope; this is parallel code
626 SharedHeap::SO_ScavengeCodeCache,
627 GenCollectedHeap::StrongAndWeakRoots,
628 &par_scan_state.to_space_root_closure(),
751 ? obj->forwardee()
752 : _g->DefNewGeneration::copy_to_survivor_space(obj);
753 oopDesc::encode_store_heap_oop_not_null(p, new_obj);
754 }
755 if (_gc_barrier) {
756 // If p points to a younger generation, mark the card.
757 if ((HeapWord*)obj < _gen_boundary) {
758 _rs->write_ref_field_gc_par(p, obj);
759 }
760 }
761 }
762 }
763
764 void ScanClosureWithParBarrier::do_oop(oop* p) { ScanClosureWithParBarrier::do_oop_work(p); }
765 void ScanClosureWithParBarrier::do_oop(narrowOop* p) { ScanClosureWithParBarrier::do_oop_work(p); }
766
767 class ParNewRefProcTaskProxy: public AbstractGangTask {
768 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
769 public:
770 ParNewRefProcTaskProxy(ProcessTask& task, ParNewGeneration& gen,
771 Generation& old_gen,
772 HeapWord* young_old_boundary,
773 ParScanThreadStateSet& state_set);
774
775 private:
776 virtual void work(uint worker_id);
777 virtual void set_for_termination(int active_workers) {
778 _state_set.terminator()->reset_for_reuse(active_workers);
779 }
780 private:
781 ParNewGeneration& _gen;
782 ProcessTask& _task;
783 Generation& _old_gen;
784 HeapWord* _young_old_boundary;
785 ParScanThreadStateSet& _state_set;
786 };
787
788 ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(
789 ProcessTask& task, ParNewGeneration& gen,
790 Generation& old_gen,
791 HeapWord* young_old_boundary,
792 ParScanThreadStateSet& state_set)
793 : AbstractGangTask("ParNewGeneration parallel reference processing"),
794 _gen(gen),
795 _task(task),
796 _old_gen(old_gen),
797 _young_old_boundary(young_old_boundary),
798 _state_set(state_set)
799 {
800 }
801
802 void ParNewRefProcTaskProxy::work(uint worker_id)
803 {
804 ResourceMark rm;
805 HandleMark hm;
806 ParScanThreadState& par_scan_state = _state_set.thread_state(worker_id);
807 par_scan_state.set_young_old_boundary(_young_old_boundary);
808 _task.work(worker_id, par_scan_state.is_alive_closure(),
809 par_scan_state.keep_alive_closure(),
810 par_scan_state.evacuate_followers_closure());
811 }
812
813 class ParNewRefEnqueueTaskProxy: public AbstractGangTask {
814 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
815 EnqueueTask& _task;
816
882 }
883
884
885 // A Generation that does parallel young-gen collection.
886
887 bool ParNewGeneration::_avoid_promotion_undo = false;
888
889 void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) {
890 assert(_promo_failure_scan_stack.is_empty(), "post condition");
891 _promo_failure_scan_stack.clear(true); // Clear cached segments.
892
893 remove_forwarding_pointers();
894 if (PrintGCDetails) {
895 gclog_or_tty->print(" (promotion failed)");
896 }
897 // All the spaces are in play for mark-sweep.
898 swap_spaces(); // Make life simpler for CMS || rescan; see 6483690.
899 from()->set_next_compaction_space(to());
900 gch->set_incremental_collection_failed();
901 // Inform the next generation that a promotion failure occurred.
902 _old_gen->promotion_failure_occurred();
903
904 // Trace promotion failure in the parallel GC threads
905 thread_state_set.trace_promotion_failed(gc_tracer);
906 // Single threaded code may have reported promotion failure to the global state
907 if (_promotion_failed_info.has_failed()) {
908 gc_tracer.report_promotion_failed(_promotion_failed_info);
909 }
910 // Reset the PromotionFailureALot counters.
911 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();)
912 }
913
914 void ParNewGeneration::collect(bool full,
915 bool clear_all_soft_refs,
916 size_t size,
917 bool is_tlab) {
918 assert(full || size > 0, "otherwise we don't want to collect");
919
920 GenCollectedHeap* gch = GenCollectedHeap::heap();
921
922 _gc_timer->register_gc_start();
923
924 assert(gch->kind() == CollectedHeap::GenCollectedHeap,
925 "not a CMS generational heap");
926 AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
927 FlexibleWorkGang* workers = gch->workers();
928 assert(workers != NULL, "Need workgang for parallel work");
929 int active_workers =
930 AdaptiveSizePolicy::calc_active_workers(workers->total_workers(),
931 workers->active_workers(),
932 Threads::number_of_non_daemon_threads());
933 workers->set_active_workers(active_workers);
934 assert(gch->n_gens() == 2,
935 "Par collection currently only works with single older gen.");
936 _old_gen = gch->old_gen();
937 // Do we have to avoid promotion_undo?
938 if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) {
939 set_avoid_promotion_undo(true);
940 }
941
942 // If the next generation is too full to accommodate worst-case promotion
943 // from this generation, pass on collection; let the next generation
944 // do it.
945 if (!collection_attempt_is_safe()) {
946 gch->set_incremental_collection_failed(); // slight lie, in that we did not even attempt one
947 return;
948 }
949 assert(to()->is_empty(), "Else not collection_attempt_is_safe");
950
951 ParNewTracer gc_tracer;
952 gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
953 gch->trace_heap_before_gc(&gc_tracer);
954
955 init_assuming_no_promotion_failure();
956
962 GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, gc_tracer.gc_id());
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, *_old_gen, *task_queues(),
983 _overflow_stacks, desired_plab_sz(), _term);
984
985 ParNewGenTask tsk(this, _old_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();
1004 IsAliveClosure is_alive(this);
1005 ScanWeakRefClosure scan_weak_ref(this);
1179 // Try allocating obj in to-space (unless too old)
1180 if (dummyOld.age() < tenuring_threshold()) {
1181 new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
1182 if (new_obj == NULL) {
1183 set_survivor_overflow(true);
1184 }
1185 }
1186
1187 if (new_obj == NULL) {
1188 // Either to-space is full or we decided to promote
1189 // try allocating obj tenured
1190
1191 // Attempt to install a null forwarding pointer (atomically),
1192 // to claim the right to install the real forwarding pointer.
1193 forward_ptr = old->forward_to_atomic(ClaimedForwardPtr);
1194 if (forward_ptr != NULL) {
1195 // someone else beat us to it.
1196 return real_forwardee(old);
1197 }
1198
1199 new_obj = _old_gen->par_promote(par_scan_state->thread_num(),
1200 old, m, sz);
1201
1202 if (new_obj == NULL) {
1203 // promotion failed, forward to self
1204 _promotion_failed = true;
1205 new_obj = old;
1206
1207 preserve_mark_if_necessary(old, m);
1208 par_scan_state->register_promotion_failure(sz);
1209 }
1210
1211 old->forward_to(new_obj);
1212 forward_ptr = NULL;
1213 } else {
1214 // Is in to-space; do copying ourselves.
1215 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
1216 forward_ptr = old->forward_to_atomic(new_obj);
1217 // Restore the mark word copied above.
1218 new_obj->set_mark(m);
1219 // Increment age if obj still in new generation
1297 oopDesc dummyOld;
1298 dummyOld.set_mark(m);
1299 assert(!dummyOld.is_forwarded(),
1300 "should not be called with forwarding pointer mark word.");
1301
1302 bool failed_to_promote = false;
1303 oop new_obj = NULL;
1304 oop forward_ptr;
1305
1306 // Try allocating obj in to-space (unless too old)
1307 if (dummyOld.age() < tenuring_threshold()) {
1308 new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
1309 if (new_obj == NULL) {
1310 set_survivor_overflow(true);
1311 }
1312 }
1313
1314 if (new_obj == NULL) {
1315 // Either to-space is full or we decided to promote
1316 // try allocating obj tenured
1317 new_obj = _old_gen->par_promote(par_scan_state->thread_num(),
1318 old, m, sz);
1319
1320 if (new_obj == NULL) {
1321 // promotion failed, forward to self
1322 forward_ptr = old->forward_to_atomic(old);
1323 new_obj = old;
1324
1325 if (forward_ptr != NULL) {
1326 return forward_ptr; // someone else succeeded
1327 }
1328
1329 _promotion_failed = true;
1330 failed_to_promote = true;
1331
1332 preserve_mark_if_necessary(old, m);
1333 par_scan_state->register_promotion_failure(sz);
1334 }
1335 } else {
1336 // Is in to-space; do copying ourselves.
1337 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
1378 simulate_overflow = true;
1379 }
1380 )
1381 if (simulate_overflow || !par_scan_state->work_queue()->push(obj_to_push)) {
1382 // Add stats for overflow pushes.
1383 push_on_overflow_list(old, par_scan_state);
1384 TASKQUEUE_STATS_ONLY(par_scan_state->taskqueue_stats().record_overflow(0));
1385 }
1386
1387 return new_obj;
1388 }
1389
1390 // Oops. Someone beat us to it. Undo the allocation. Where did we
1391 // allocate it?
1392 if (is_in_reserved(new_obj)) {
1393 // Must be in to_space.
1394 assert(to()->is_in_reserved(new_obj), "Checking");
1395 par_scan_state->undo_alloc_in_to_space((HeapWord*)new_obj, sz);
1396 } else {
1397 assert(!_avoid_promotion_undo, "Should not be here if avoiding.");
1398 _old_gen->par_promote_alloc_undo(par_scan_state->thread_num(),
1399 (HeapWord*)new_obj, sz);
1400 }
1401
1402 return forward_ptr;
1403 }
1404
1405 #ifndef PRODUCT
1406 // It's OK to call this multi-threaded; the worst thing
1407 // that can happen is that we'll get a bunch of closely
1408 // spaced simulated overflows, but that's OK, in fact
1409 // probably good as it would exercise the overflow code
1410 // under contention.
1411 bool ParNewGeneration::should_simulate_overflow() {
1412 if (_overflow_counter-- <= 0) { // just being defensive
1413 _overflow_counter = ParGCWorkQueueOverflowInterval;
1414 return true;
1415 } else {
1416 return false;
1417 }
1418 }
|