< prev index next >

src/share/vm/gc/cms/parNewGeneration.cpp

Print this page
rev 8461 : 8086056: ParNew: auto-tune ParGCCardsPerStrideChunk
Summary: Automatically calculate ParGCCardsPerStrideChunk based on the old gen capacity.
Reviewed-by:
rev 8441 : 8081007: Remove redundant active worker variables and calls in ParNewGeneration::collect
Reviewed-by: pliden, kbarrett, ehelin
rev 8409 : 8080879: Remove FlexibleWorkGang::set_for_termination
Reviewed-by: brutisso, kbarrett, pliden
rev 8404 : 8080876: Replace unnecessary MAX2(ParallelGCThreads, 1) calls with ParallelGCThreads
Reviewed-by: kbarrett, mgerdin
rev 8399 : 8080113: Remove CollectedHeap::set_par_threads()
Reviewed-by: jmasa, kbarrett
rev 8397 : 8080111: Remove SubTaskDone::_n_threads
Reviewed-by: jmasa, kbarrett
rev 8396 : 8080110: Remove usage of CollectedHeap::n_par_threads() from root processing
Reviewed-by: jmasa, kbarrett
rev 8362 : 8079792: GC directory structure cleanup
Reviewed-by: brutisso, stefank, david


 603                          GenCollectedHeap::StrongAndWeakRoots,
 604                          &par_scan_state.to_space_root_closure(),
 605                          &par_scan_state.older_gen_closure(),
 606                          &cld_scan_closure);
 607 
 608   par_scan_state.end_strong_roots();
 609 
 610   // "evacuate followers".
 611   par_scan_state.evacuate_followers_closure().do_void();
 612 }
 613 
 614 #ifdef _MSC_VER
 615 #pragma warning( push )
 616 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
 617 #endif
 618 ParNewGeneration::
 619 ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level)
 620   : DefNewGeneration(rs, initial_byte_size, level, "PCopy"),
 621   _overflow_list(NULL),
 622   _is_alive_closure(this),
 623   _plab_stats(YoungPLABSize, PLABWeight)

 624 {
 625   NOT_PRODUCT(_overflow_counter = ParGCWorkQueueOverflowInterval;)
 626   NOT_PRODUCT(_num_par_pushes = 0;)
 627   _task_queues = new ObjToScanQueueSet(ParallelGCThreads);
 628   guarantee(_task_queues != NULL, "task_queues allocation failure.");
 629 
 630   for (uint i1 = 0; i1 < ParallelGCThreads; i1++) {
 631     ObjToScanQueue *q = new ObjToScanQueue();
 632     guarantee(q != NULL, "work_queue Allocation failure.");
 633     _task_queues->register_queue(i1, q);
 634   }
 635 
 636   for (uint i2 = 0; i2 < ParallelGCThreads; i2++)
 637     _task_queues->queue(i2)->initialize();
 638 
 639   _overflow_stacks = NULL;
 640   if (ParGCUseLocalOverflow) {
 641 
 642     // typedef to workaround NEW_C_HEAP_ARRAY macro, which can not deal
 643     // with ','
 644     typedef Stack<oop, mtGC> GCOopStack;
 645 
 646     _overflow_stacks = NEW_C_HEAP_ARRAY(GCOopStack, ParallelGCThreads, mtGC);
 647     for (size_t i = 0; i < ParallelGCThreads; ++i) {
 648       new (_overflow_stacks + i) Stack<oop, mtGC>();
 649     }
 650   }
 651 
 652   if (UsePerfData) {
 653     EXCEPTION_MARK;
 654     ResourceMark rm;
 655 
 656     const char* cname =
 657          PerfDataManager::counter_name(_gen_counters->name_space(), "threads");
 658     PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None,
 659                                      ParallelGCThreads, CHECK);
 660   }




 661 }
 662 #ifdef _MSC_VER
 663 #pragma warning( pop )
 664 #endif
 665 
 666 // ParNewGeneration::
 667 ParKeepAliveClosure::ParKeepAliveClosure(ParScanWeakRefClosure* cl) :
 668   DefNewGeneration::KeepAliveClosure(cl), _par_cl(cl) {}
 669 
 670 template <class T>
 671 void /*ParNewGeneration::*/ParKeepAliveClosure::do_oop_work(T* p) {
 672 #ifdef ASSERT
 673   {
 674     assert(!oopDesc::is_null(*p), "expected non-null ref");
 675     oop obj = oopDesc::load_decode_heap_oop_not_null(p);
 676     // We never expect to see a null reference being processed
 677     // as a weak reference.
 678     assert(obj->is_oop(), "expected an oop while scanning weak refs");
 679   }
 680 #endif // ASSERT


 863   if (PrintGCDetails) {
 864     gclog_or_tty->print(" (promotion failed)");
 865   }
 866   // All the spaces are in play for mark-sweep.
 867   swap_spaces();  // Make life simpler for CMS || rescan; see 6483690.
 868   from()->set_next_compaction_space(to());
 869   gch->set_incremental_collection_failed();
 870   // Inform the next generation that a promotion failure occurred.
 871   _old_gen->promotion_failure_occurred();
 872 
 873   // Trace promotion failure in the parallel GC threads
 874   thread_state_set.trace_promotion_failed(gc_tracer());
 875   // Single threaded code may have reported promotion failure to the global state
 876   if (_promotion_failed_info.has_failed()) {
 877     _gc_tracer.report_promotion_failed(_promotion_failed_info);
 878   }
 879   // Reset the PromotionFailureALot counters.
 880   NOT_PRODUCT(gch->reset_promotion_should_fail();)
 881 }
 882 




































 883 void ParNewGeneration::collect(bool   full,
 884                                bool   clear_all_soft_refs,
 885                                size_t size,
 886                                bool   is_tlab) {
 887   assert(full || size > 0, "otherwise we don't want to collect");
 888 
 889   GenCollectedHeap* gch = GenCollectedHeap::heap();
 890 
 891   _gc_timer->register_gc_start();
 892 
 893   AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
 894   FlexibleWorkGang* workers = gch->workers();
 895   assert(workers != NULL, "Need workgang for parallel work");
 896   uint active_workers =
 897        AdaptiveSizePolicy::calc_active_workers(workers->total_workers(),
 898                                                workers->active_workers(),
 899                                                Threads::number_of_non_daemon_threads());
 900   workers->set_active_workers(active_workers);
 901   _old_gen = gch->old_gen();
 902 


 908     return;
 909   }
 910   assert(to()->is_empty(), "Else not collection_attempt_is_safe");
 911 
 912   _gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
 913   gch->trace_heap_before_gc(gc_tracer());
 914 
 915   init_assuming_no_promotion_failure();
 916 
 917   if (UseAdaptiveSizePolicy) {
 918     set_survivor_overflow(false);
 919     size_policy->minor_collection_begin();
 920   }
 921 
 922   GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, _gc_tracer.gc_id());
 923   // Capture heap used before collection (for printing).
 924   size_t gch_prev_used = gch->used();
 925 
 926   age_table()->clear();
 927   to()->clear(SpaceDecorator::Mangle);

 928 
 929   gch->save_marks();
 930 
 931   // Set the correct parallelism (number of queues) in the reference processor
 932   ref_processor()->set_active_mt_degree(active_workers);
 933 
 934   // Always set the terminator for the active number of workers
 935   // because only those workers go through the termination protocol.
 936   ParallelTaskTerminator _term(active_workers, task_queues());
 937   ParScanThreadStateSet thread_state_set(active_workers,
 938                                          *to(), *this, *_old_gen, *task_queues(),
 939                                          _overflow_stacks, desired_plab_sz(), _term);
 940 
 941   thread_state_set.reset(active_workers, promotion_failed());
 942 
 943   {
 944     StrongRootsScope srs(active_workers);
 945 
 946     ParNewGenTask tsk(this, _old_gen, reserved().end(), &thread_state_set, &srs);
 947     gch->rem_set()->prepare_for_younger_refs_iterate(true);




 603                          GenCollectedHeap::StrongAndWeakRoots,
 604                          &par_scan_state.to_space_root_closure(),
 605                          &par_scan_state.older_gen_closure(),
 606                          &cld_scan_closure);
 607 
 608   par_scan_state.end_strong_roots();
 609 
 610   // "evacuate followers".
 611   par_scan_state.evacuate_followers_closure().do_void();
 612 }
 613 
 614 #ifdef _MSC_VER
 615 #pragma warning( push )
 616 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
 617 #endif
 618 ParNewGeneration::
 619 ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level)
 620   : DefNewGeneration(rs, initial_byte_size, level, "PCopy"),
 621   _overflow_list(NULL),
 622   _is_alive_closure(this),
 623   _plab_stats(YoungPLABSize, PLABWeight),
 624   _should_adjust_cards_per_stride(false)
 625 {
 626   NOT_PRODUCT(_overflow_counter = ParGCWorkQueueOverflowInterval;)
 627   NOT_PRODUCT(_num_par_pushes = 0;)
 628   _task_queues = new ObjToScanQueueSet(ParallelGCThreads);
 629   guarantee(_task_queues != NULL, "task_queues allocation failure.");
 630 
 631   for (uint i1 = 0; i1 < ParallelGCThreads; i1++) {
 632     ObjToScanQueue *q = new ObjToScanQueue();
 633     guarantee(q != NULL, "work_queue Allocation failure.");
 634     _task_queues->register_queue(i1, q);
 635   }
 636 
 637   for (uint i2 = 0; i2 < ParallelGCThreads; i2++)
 638     _task_queues->queue(i2)->initialize();
 639 
 640   _overflow_stacks = NULL;
 641   if (ParGCUseLocalOverflow) {
 642 
 643     // typedef to workaround NEW_C_HEAP_ARRAY macro, which can not deal
 644     // with ','
 645     typedef Stack<oop, mtGC> GCOopStack;
 646 
 647     _overflow_stacks = NEW_C_HEAP_ARRAY(GCOopStack, ParallelGCThreads, mtGC);
 648     for (size_t i = 0; i < ParallelGCThreads; ++i) {
 649       new (_overflow_stacks + i) Stack<oop, mtGC>();
 650     }
 651   }
 652 
 653   if (UsePerfData) {
 654     EXCEPTION_MARK;
 655     ResourceMark rm;
 656 
 657     const char* cname =
 658          PerfDataManager::counter_name(_gen_counters->name_space(), "threads");
 659     PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None,
 660                                      ParallelGCThreads, CHECK);
 661   }
 662 
 663   // we'll automatically calculate ParGCCardsPerStrideChunk if it has
 664   // not been explicitly set on the command line
 665   _should_adjust_cards_per_stride = FLAG_IS_DEFAULT(ParGCCardsPerStrideChunk);
 666 }
 667 #ifdef _MSC_VER
 668 #pragma warning( pop )
 669 #endif
 670 
 671 // ParNewGeneration::
 672 ParKeepAliveClosure::ParKeepAliveClosure(ParScanWeakRefClosure* cl) :
 673   DefNewGeneration::KeepAliveClosure(cl), _par_cl(cl) {}
 674 
 675 template <class T>
 676 void /*ParNewGeneration::*/ParKeepAliveClosure::do_oop_work(T* p) {
 677 #ifdef ASSERT
 678   {
 679     assert(!oopDesc::is_null(*p), "expected non-null ref");
 680     oop obj = oopDesc::load_decode_heap_oop_not_null(p);
 681     // We never expect to see a null reference being processed
 682     // as a weak reference.
 683     assert(obj->is_oop(), "expected an oop while scanning weak refs");
 684   }
 685 #endif // ASSERT


 868   if (PrintGCDetails) {
 869     gclog_or_tty->print(" (promotion failed)");
 870   }
 871   // All the spaces are in play for mark-sweep.
 872   swap_spaces();  // Make life simpler for CMS || rescan; see 6483690.
 873   from()->set_next_compaction_space(to());
 874   gch->set_incremental_collection_failed();
 875   // Inform the next generation that a promotion failure occurred.
 876   _old_gen->promotion_failure_occurred();
 877 
 878   // Trace promotion failure in the parallel GC threads
 879   thread_state_set.trace_promotion_failed(gc_tracer());
 880   // Single threaded code may have reported promotion failure to the global state
 881   if (_promotion_failed_info.has_failed()) {
 882     _gc_tracer.report_promotion_failed(_promotion_failed_info);
 883   }
 884   // Reset the PromotionFailureALot counters.
 885   NOT_PRODUCT(gch->reset_promotion_should_fail();)
 886 }
 887 
 888 void ParNewGeneration::adjust_cards_per_stride(const Generation& old_gen) {
 889   if (!_should_adjust_cards_per_stride) return;
 890 
 891   const size_t MinOldGenCapacity =      G;
 892   const size_t MaxOldGenCapacity = 16 * G;
 893   assert(MinOldGenCapacity <= MaxOldGenCapacity, "sanity");
 894   const size_t OldGenCapacityDiff = MaxOldGenCapacity - MinOldGenCapacity;
 895 
 896   const intx MinStrideChunkSize =   256;
 897   const intx MaxStrideChunkSize = 8 * K;
 898   assert(MinStrideChunkSize <= MaxStrideChunkSize, "sanity");
 899   const intx StrideChunkSizeDiff = MaxStrideChunkSize - MinStrideChunkSize;
 900 
 901   const size_t capacity = old_gen.capacity();
 902   // adj_capacity = capacity bounded by {Min,Max}OldGenCapacity
 903   size_t adj_capacity = capacity;
 904   adj_capacity = MAX2(adj_capacity, MinOldGenCapacity);
 905   adj_capacity = MIN2(adj_capacity, MaxOldGenCapacity);
 906 
 907   const size_t capacity_offset = adj_capacity - MinOldGenCapacity;
 908   assert(capacity_offset && capacity_offset <= OldGenCapacityDiff,
 909          "sanity");
 910   const double r = (double) capacity_offset / (double) OldGenCapacityDiff;
 911   const intx stride_chunk_offset = (intx) (r * (double) StrideChunkSizeDiff);
 912   const int stride_chunk_size_log =
 913             log2_intptr((intptr_t) (MinStrideChunkSize + stride_chunk_offset));
 914   const intx stride_chunk_size = (intx) 1 << stride_chunk_size_log;
 915 
 916   assert(MinStrideChunkSize <= stride_chunk_size &&
 917          stride_chunk_size <= MaxStrideChunkSize &&
 918          is_power_of_2((intptr_t) stride_chunk_size),
 919          err_msg("stride_chunk_size: "INTX_FORMAT, stride_chunk_size));
 920 
 921   FLAG_SET_ERGO(intx, ParGCCardsPerStrideChunk, stride_chunk_size);
 922 }
 923 
 924 void ParNewGeneration::collect(bool   full,
 925                                bool   clear_all_soft_refs,
 926                                size_t size,
 927                                bool   is_tlab) {
 928   assert(full || size > 0, "otherwise we don't want to collect");
 929 
 930   GenCollectedHeap* gch = GenCollectedHeap::heap();
 931 
 932   _gc_timer->register_gc_start();
 933 
 934   AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
 935   FlexibleWorkGang* workers = gch->workers();
 936   assert(workers != NULL, "Need workgang for parallel work");
 937   uint active_workers =
 938        AdaptiveSizePolicy::calc_active_workers(workers->total_workers(),
 939                                                workers->active_workers(),
 940                                                Threads::number_of_non_daemon_threads());
 941   workers->set_active_workers(active_workers);
 942   _old_gen = gch->old_gen();
 943 


 949     return;
 950   }
 951   assert(to()->is_empty(), "Else not collection_attempt_is_safe");
 952 
 953   _gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
 954   gch->trace_heap_before_gc(gc_tracer());
 955 
 956   init_assuming_no_promotion_failure();
 957 
 958   if (UseAdaptiveSizePolicy) {
 959     set_survivor_overflow(false);
 960     size_policy->minor_collection_begin();
 961   }
 962 
 963   GCTraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, NULL, _gc_tracer.gc_id());
 964   // Capture heap used before collection (for printing).
 965   size_t gch_prev_used = gch->used();
 966 
 967   age_table()->clear();
 968   to()->clear(SpaceDecorator::Mangle);
 969   adjust_cards_per_stride(*_old_gen);
 970 
 971   gch->save_marks();
 972 
 973   // Set the correct parallelism (number of queues) in the reference processor
 974   ref_processor()->set_active_mt_degree(active_workers);
 975 
 976   // Always set the terminator for the active number of workers
 977   // because only those workers go through the termination protocol.
 978   ParallelTaskTerminator _term(active_workers, task_queues());
 979   ParScanThreadStateSet thread_state_set(active_workers,
 980                                          *to(), *this, *_old_gen, *task_queues(),
 981                                          _overflow_stacks, desired_plab_sz(), _term);
 982 
 983   thread_state_set.reset(active_workers, promotion_failed());
 984 
 985   {
 986     StrongRootsScope srs(active_workers);
 987 
 988     ParNewGenTask tsk(this, _old_gen, reserved().end(), &thread_state_set, &srs);
 989     gch->rem_set()->prepare_for_younger_refs_iterate(true);


< prev index next >