60 #ifdef _MSC_VER |
60 #ifdef _MSC_VER |
61 #pragma warning( push ) |
61 #pragma warning( push ) |
62 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list |
62 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list |
63 #endif |
63 #endif |
64 ParScanThreadState::ParScanThreadState(Space* to_space_, |
64 ParScanThreadState::ParScanThreadState(Space* to_space_, |
65 ParNewGeneration* gen_, |
65 ParNewGeneration* young_gen_, |
66 Generation* old_gen_, |
66 Generation* old_gen_, |
67 int thread_num_, |
67 int thread_num_, |
68 ObjToScanQueueSet* work_queue_set_, |
68 ObjToScanQueueSet* work_queue_set_, |
69 Stack<oop, mtGC>* overflow_stacks_, |
69 Stack<oop, mtGC>* overflow_stacks_, |
70 size_t desired_plab_sz_, |
70 size_t desired_plab_sz_, |
71 ParallelTaskTerminator& term_) : |
71 ParallelTaskTerminator& term_) : |
72 _to_space(to_space_), _old_gen(old_gen_), _young_gen(gen_), _thread_num(thread_num_), |
72 _to_space(to_space_), _old_gen(old_gen_), _young_gen(young_gen_), _thread_num(thread_num_), |
73 _work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false), |
73 _work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false), |
74 _overflow_stack(overflow_stacks_ ? overflow_stacks_ + thread_num_ : NULL), |
74 _overflow_stack(overflow_stacks_ ? overflow_stacks_ + thread_num_ : NULL), |
75 _ageTable(false), // false ==> not the global age table, no perf data. |
75 _ageTable(false), // false ==> not the global age table, no perf data. |
76 _to_space_alloc_buffer(desired_plab_sz_), |
76 _to_space_alloc_buffer(desired_plab_sz_), |
77 _to_space_closure(gen_, this), _old_gen_closure(gen_, this), |
77 _to_space_closure(young_gen_, this), _old_gen_closure(young_gen_, this), |
78 _to_space_root_closure(gen_, this), _old_gen_root_closure(gen_, this), |
78 _to_space_root_closure(young_gen_, this), _old_gen_root_closure(young_gen_, this), |
79 _older_gen_closure(gen_, this), |
79 _older_gen_closure(young_gen_, this), |
80 _evacuate_followers(this, &_to_space_closure, &_old_gen_closure, |
80 _evacuate_followers(this, &_to_space_closure, &_old_gen_closure, |
81 &_to_space_root_closure, gen_, &_old_gen_root_closure, |
81 &_to_space_root_closure, young_gen_, &_old_gen_root_closure, |
82 work_queue_set_, &term_), |
82 work_queue_set_, &term_), |
83 _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this), |
83 _is_alive_closure(young_gen_), _scan_weak_ref_closure(young_gen_, this), |
84 _keep_alive_closure(&_scan_weak_ref_closure), |
84 _keep_alive_closure(&_scan_weak_ref_closure), |
85 _strong_roots_time(0.0), _term_time(0.0) |
85 _strong_roots_time(0.0), _term_time(0.0) |
86 { |
86 { |
87 #if TASKQUEUE_STATS |
87 #if TASKQUEUE_STATS |
88 _term_attempts = 0; |
88 _term_attempts = 0; |
479 |
479 |
480 ParScanClosure::ParScanClosure(ParNewGeneration* g, |
480 ParScanClosure::ParScanClosure(ParNewGeneration* g, |
481 ParScanThreadState* par_scan_state) : |
481 ParScanThreadState* par_scan_state) : |
482 OopsInKlassOrGenClosure(g), _par_scan_state(par_scan_state), _g(g) |
482 OopsInKlassOrGenClosure(g), _par_scan_state(par_scan_state), _g(g) |
483 { |
483 { |
484 assert(_g->level() == 0, "Optimized for youngest generation"); |
|
485 _boundary = _g->reserved().end(); |
484 _boundary = _g->reserved().end(); |
486 } |
485 } |
487 |
486 |
488 void ParScanWithBarrierClosure::do_oop(oop* p) { ParScanClosure::do_oop_work(p, true, false); } |
487 void ParScanWithBarrierClosure::do_oop(oop* p) { ParScanClosure::do_oop_work(p, true, false); } |
489 void ParScanWithBarrierClosure::do_oop(narrowOop* p) { ParScanClosure::do_oop_work(p, true, false); } |
488 void ParScanWithBarrierClosure::do_oop(narrowOop* p) { ParScanClosure::do_oop_work(p, true, false); } |
564 "Broken overflow list?"); |
563 "Broken overflow list?"); |
565 // Finish the last termination pause. |
564 // Finish the last termination pause. |
566 par_scan_state()->end_term_time(); |
565 par_scan_state()->end_term_time(); |
567 } |
566 } |
568 |
567 |
569 ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* old_gen, |
568 ParNewGenTask::ParNewGenTask(ParNewGeneration* young_gen, Generation* old_gen, |
570 HeapWord* young_old_boundary, ParScanThreadStateSet* state_set, |
569 HeapWord* young_old_boundary, ParScanThreadStateSet* state_set, |
571 StrongRootsScope* strong_roots_scope) : |
570 StrongRootsScope* strong_roots_scope) : |
572 AbstractGangTask("ParNewGeneration collection"), |
571 AbstractGangTask("ParNewGeneration collection"), |
573 _gen(gen), _old_gen(old_gen), |
572 _young_gen(young_gen), _old_gen(old_gen), |
574 _young_old_boundary(young_old_boundary), |
573 _young_old_boundary(young_old_boundary), |
575 _state_set(state_set), |
574 _state_set(state_set), |
576 _strong_roots_scope(strong_roots_scope) |
575 _strong_roots_scope(strong_roots_scope) |
577 {} |
576 {} |
578 |
577 |
594 &par_scan_state.to_space_root_closure(), |
593 &par_scan_state.to_space_root_closure(), |
595 false); |
594 false); |
596 |
595 |
597 par_scan_state.start_strong_roots(); |
596 par_scan_state.start_strong_roots(); |
598 gch->gen_process_roots(_strong_roots_scope, |
597 gch->gen_process_roots(_strong_roots_scope, |
599 _gen->level(), |
598 GenCollectedHeap::YoungGen, |
600 true, // Process younger gens, if any, |
599 true, // Process younger gens, if any, |
601 // as strong roots. |
600 // as strong roots. |
602 GenCollectedHeap::SO_ScavengeCodeCache, |
601 GenCollectedHeap::SO_ScavengeCodeCache, |
603 GenCollectedHeap::StrongAndWeakRoots, |
602 GenCollectedHeap::StrongAndWeakRoots, |
604 &par_scan_state.to_space_root_closure(), |
603 &par_scan_state.to_space_root_closure(), |
614 #ifdef _MSC_VER |
613 #ifdef _MSC_VER |
615 #pragma warning( push ) |
614 #pragma warning( push ) |
616 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list |
615 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list |
617 #endif |
616 #endif |
618 ParNewGeneration:: |
617 ParNewGeneration:: |
619 ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level) |
618 ParNewGeneration(ReservedSpace rs, size_t initial_byte_size) |
620 : DefNewGeneration(rs, initial_byte_size, level, "PCopy"), |
619 : DefNewGeneration(rs, initial_byte_size, "PCopy"), |
621 _overflow_list(NULL), |
620 _overflow_list(NULL), |
622 _is_alive_closure(this), |
621 _is_alive_closure(this), |
623 _plab_stats(YoungPLABSize, PLABWeight) |
622 _plab_stats(YoungPLABSize, PLABWeight) |
624 { |
623 { |
625 NOT_PRODUCT(_overflow_counter = ParGCWorkQueueOverflowInterval;) |
624 NOT_PRODUCT(_overflow_counter = ParGCWorkQueueOverflowInterval;) |
750 ParScanThreadStateSet& state_set); |
749 ParScanThreadStateSet& state_set); |
751 |
750 |
752 private: |
751 private: |
753 virtual void work(uint worker_id); |
752 virtual void work(uint worker_id); |
754 private: |
753 private: |
755 ParNewGeneration& _gen; |
754 ParNewGeneration& _young_gen; |
756 ProcessTask& _task; |
755 ProcessTask& _task; |
757 Generation& _old_gen; |
756 Generation& _old_gen; |
758 HeapWord* _young_old_boundary; |
757 HeapWord* _young_old_boundary; |
759 ParScanThreadStateSet& _state_set; |
758 ParScanThreadStateSet& _state_set; |
760 }; |
759 }; |
761 |
760 |
762 ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(ProcessTask& task, |
761 ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(ProcessTask& task, |
763 ParNewGeneration& gen, |
762 ParNewGeneration& young_gen, |
764 Generation& old_gen, |
763 Generation& old_gen, |
765 HeapWord* young_old_boundary, |
764 HeapWord* young_old_boundary, |
766 ParScanThreadStateSet& state_set) |
765 ParScanThreadStateSet& state_set) |
767 : AbstractGangTask("ParNewGeneration parallel reference processing"), |
766 : AbstractGangTask("ParNewGeneration parallel reference processing"), |
768 _gen(gen), |
767 _young_gen(young_gen), |
769 _task(task), |
768 _task(task), |
770 _old_gen(old_gen), |
769 _old_gen(old_gen), |
771 _young_old_boundary(young_old_boundary), |
770 _young_old_boundary(young_old_boundary), |
772 _state_set(state_set) |
771 _state_set(state_set) |
773 { |
772 { |
804 void ParNewRefProcTaskExecutor::execute(ProcessTask& task) |
803 void ParNewRefProcTaskExecutor::execute(ProcessTask& task) |
805 { |
804 { |
806 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
805 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
807 FlexibleWorkGang* workers = gch->workers(); |
806 FlexibleWorkGang* workers = gch->workers(); |
808 assert(workers != NULL, "Need parallel worker threads."); |
807 assert(workers != NULL, "Need parallel worker threads."); |
809 _state_set.reset(workers->active_workers(), _generation.promotion_failed()); |
808 _state_set.reset(workers->active_workers(), _young_gen.promotion_failed()); |
810 ParNewRefProcTaskProxy rp_task(task, _generation, *_generation.next_gen(), |
809 ParNewRefProcTaskProxy rp_task(task, _young_gen, _old_gen, |
811 _generation.reserved().end(), _state_set); |
810 _young_gen.reserved().end(), _state_set); |
812 workers->run_task(&rp_task); |
811 workers->run_task(&rp_task); |
813 _state_set.reset(0 /* bad value in debug if not reset */, |
812 _state_set.reset(0 /* bad value in debug if not reset */, |
814 _generation.promotion_failed()); |
813 _young_gen.promotion_failed()); |
815 } |
814 } |
816 |
815 |
817 void ParNewRefProcTaskExecutor::execute(EnqueueTask& task) |
816 void ParNewRefProcTaskExecutor::execute(EnqueueTask& task) |
818 { |
817 { |
819 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
818 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
833 ScanClosureWithParBarrier:: |
832 ScanClosureWithParBarrier:: |
834 ScanClosureWithParBarrier(ParNewGeneration* g, bool gc_barrier) : |
833 ScanClosureWithParBarrier(ParNewGeneration* g, bool gc_barrier) : |
835 ScanClosure(g, gc_barrier) {} |
834 ScanClosure(g, gc_barrier) {} |
836 |
835 |
837 EvacuateFollowersClosureGeneral:: |
836 EvacuateFollowersClosureGeneral:: |
838 EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, int level, |
837 EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, |
839 OopsInGenClosure* cur, |
838 OopsInGenClosure* cur, |
840 OopsInGenClosure* older) : |
839 OopsInGenClosure* older) : |
841 _gch(gch), _level(level), |
840 _gch(gch), |
842 _scan_cur_or_nonheap(cur), _scan_older(older) |
841 _scan_cur_or_nonheap(cur), _scan_older(older) |
843 {} |
842 {} |
844 |
843 |
845 void EvacuateFollowersClosureGeneral::do_void() { |
844 void EvacuateFollowersClosureGeneral::do_void() { |
846 do { |
845 do { |
847 // Beware: this call will lead to closure applications via virtual |
846 // Beware: this call will lead to closure applications via virtual |
848 // calls. |
847 // calls. |
849 _gch->oop_since_save_marks_iterate(_level, |
848 _gch->oop_since_save_marks_iterate(GenCollectedHeap::YoungGen, |
850 _scan_cur_or_nonheap, |
849 _scan_cur_or_nonheap, |
851 _scan_older); |
850 _scan_older); |
852 } while (!_gch->no_allocs_since_save_marks(_level)); |
851 } while (!_gch->no_allocs_since_save_marks(true /* include_young */)); |
853 } |
852 } |
854 |
853 |
855 |
854 |
856 // A Generation that does parallel young-gen collection. |
855 // A Generation that does parallel young-gen collection. |
857 |
856 |
970 ScanWeakRefClosure scan_weak_ref(this); |
969 ScanWeakRefClosure scan_weak_ref(this); |
971 KeepAliveClosure keep_alive(&scan_weak_ref); |
970 KeepAliveClosure keep_alive(&scan_weak_ref); |
972 ScanClosure scan_without_gc_barrier(this, false); |
971 ScanClosure scan_without_gc_barrier(this, false); |
973 ScanClosureWithParBarrier scan_with_gc_barrier(this, true); |
972 ScanClosureWithParBarrier scan_with_gc_barrier(this, true); |
974 set_promo_failure_scan_stack_closure(&scan_without_gc_barrier); |
973 set_promo_failure_scan_stack_closure(&scan_without_gc_barrier); |
975 EvacuateFollowersClosureGeneral evacuate_followers(gch, _level, |
974 EvacuateFollowersClosureGeneral evacuate_followers(gch, |
976 &scan_without_gc_barrier, &scan_with_gc_barrier); |
975 &scan_without_gc_barrier, &scan_with_gc_barrier); |
977 rp->setup_policy(clear_all_soft_refs); |
976 rp->setup_policy(clear_all_soft_refs); |
978 // Can the mt_degree be set later (at run_task() time would be best)? |
977 // Can the mt_degree be set later (at run_task() time would be best)? |
979 rp->set_active_mt_degree(active_workers); |
978 rp->set_active_mt_degree(active_workers); |
980 ReferenceProcessorStats stats; |
979 ReferenceProcessorStats stats; |
981 if (rp->processing_is_mt()) { |
980 if (rp->processing_is_mt()) { |
982 ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); |
981 ParNewRefProcTaskExecutor task_executor(*this, *_old_gen, thread_state_set); |
983 stats = rp->process_discovered_references(&is_alive, &keep_alive, |
982 stats = rp->process_discovered_references(&is_alive, &keep_alive, |
984 &evacuate_followers, &task_executor, |
983 &evacuate_followers, &task_executor, |
985 _gc_timer, _gc_tracer.gc_id()); |
984 _gc_timer, _gc_tracer.gc_id()); |
986 } else { |
985 } else { |
987 thread_state_set.flush(); |
986 thread_state_set.flush(); |
1043 jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; |
1042 jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; |
1044 update_time_of_last_gc(now); |
1043 update_time_of_last_gc(now); |
1045 |
1044 |
1046 rp->set_enqueuing_is_done(true); |
1045 rp->set_enqueuing_is_done(true); |
1047 if (rp->processing_is_mt()) { |
1046 if (rp->processing_is_mt()) { |
1048 ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); |
1047 ParNewRefProcTaskExecutor task_executor(*this, *_old_gen, thread_state_set); |
1049 rp->enqueue_discovered_references(&task_executor); |
1048 rp->enqueue_discovered_references(&task_executor); |
1050 } else { |
1049 } else { |
1051 rp->enqueue_discovered_references(NULL); |
1050 rp->enqueue_discovered_references(NULL); |
1052 } |
1051 } |
1053 rp->verify_no_references_recorded(); |
1052 rp->verify_no_references_recorded(); |