Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @ 4728:441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
Summary: Change variables representing the number of GC workers to uint from int and size_t. Change the parameter in work(int i) to work(uint worker_id).
Reviewed-by: brutisso, tonyp
author | jmasa |
---|---|
date | Wed, 14 Dec 2011 13:34:57 -0800 |
parents | f1391adc6681 |
children | be649fefcdc2 |
comparison
equal
deleted
inserted
replaced
4727:67fdcb391461 | 4728:441e946dc1af |
---|---|
3777 | 3777 |
3778 virtual void set_for_termination(int active_workers) { | 3778 virtual void set_for_termination(int active_workers) { |
3779 terminator()->reset_for_reuse(active_workers); | 3779 terminator()->reset_for_reuse(active_workers); |
3780 } | 3780 } |
3781 | 3781 |
3782 void work(int i); | 3782 void work(uint worker_id); |
3783 bool should_yield() { | 3783 bool should_yield() { |
3784 return ConcurrentMarkSweepThread::should_yield() | 3784 return ConcurrentMarkSweepThread::should_yield() |
3785 && !_collector->foregroundGCIsActive() | 3785 && !_collector->foregroundGCIsActive() |
3786 && _asynch; | 3786 && _asynch; |
3787 } | 3787 } |
3850 // . check global overflow stack; steal a batch of oops and trace | 3850 // . check global overflow stack; steal a batch of oops and trace |
3851 // . try to steal from other threads oif GOS is empty | 3851 // . try to steal from other threads oif GOS is empty |
3852 // . if neither is available, offer termination | 3852 // . if neither is available, offer termination |
3853 // -- Terminate and return result | 3853 // -- Terminate and return result |
3854 // | 3854 // |
3855 void CMSConcMarkingTask::work(int i) { | 3855 void CMSConcMarkingTask::work(uint worker_id) { |
3856 elapsedTimer _timer; | 3856 elapsedTimer _timer; |
3857 ResourceMark rm; | 3857 ResourceMark rm; |
3858 HandleMark hm; | 3858 HandleMark hm; |
3859 | 3859 |
3860 DEBUG_ONLY(_collector->verify_overflow_empty();) | 3860 DEBUG_ONLY(_collector->verify_overflow_empty();) |
3861 | 3861 |
3862 // Before we begin work, our work queue should be empty | 3862 // Before we begin work, our work queue should be empty |
3863 assert(work_queue(i)->size() == 0, "Expected to be empty"); | 3863 assert(work_queue(worker_id)->size() == 0, "Expected to be empty"); |
3864 // Scan the bitmap covering _cms_space, tracing through grey objects. | 3864 // Scan the bitmap covering _cms_space, tracing through grey objects. |
3865 _timer.start(); | 3865 _timer.start(); |
3866 do_scan_and_mark(i, _cms_space); | 3866 do_scan_and_mark(worker_id, _cms_space); |
3867 _timer.stop(); | 3867 _timer.stop(); |
3868 if (PrintCMSStatistics != 0) { | 3868 if (PrintCMSStatistics != 0) { |
3869 gclog_or_tty->print_cr("Finished cms space scanning in %dth thread: %3.3f sec", | 3869 gclog_or_tty->print_cr("Finished cms space scanning in %dth thread: %3.3f sec", |
3870 i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers | 3870 worker_id, _timer.seconds()); |
3871 // XXX: need xxx/xxx type of notation, two timers | |
3871 } | 3872 } |
3872 | 3873 |
3873 // ... do the same for the _perm_space | 3874 // ... do the same for the _perm_space |
3874 _timer.reset(); | 3875 _timer.reset(); |
3875 _timer.start(); | 3876 _timer.start(); |
3876 do_scan_and_mark(i, _perm_space); | 3877 do_scan_and_mark(worker_id, _perm_space); |
3877 _timer.stop(); | 3878 _timer.stop(); |
3878 if (PrintCMSStatistics != 0) { | 3879 if (PrintCMSStatistics != 0) { |
3879 gclog_or_tty->print_cr("Finished perm space scanning in %dth thread: %3.3f sec", | 3880 gclog_or_tty->print_cr("Finished perm space scanning in %dth thread: %3.3f sec", |
3880 i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers | 3881 worker_id, _timer.seconds()); |
3882 // XXX: need xxx/xxx type of notation, two timers | |
3881 } | 3883 } |
3882 | 3884 |
3883 // ... do work stealing | 3885 // ... do work stealing |
3884 _timer.reset(); | 3886 _timer.reset(); |
3885 _timer.start(); | 3887 _timer.start(); |
3886 do_work_steal(i); | 3888 do_work_steal(worker_id); |
3887 _timer.stop(); | 3889 _timer.stop(); |
3888 if (PrintCMSStatistics != 0) { | 3890 if (PrintCMSStatistics != 0) { |
3889 gclog_or_tty->print_cr("Finished work stealing in %dth thread: %3.3f sec", | 3891 gclog_or_tty->print_cr("Finished work stealing in %dth thread: %3.3f sec", |
3890 i, _timer.seconds()); // XXX: need xxx/xxx type of notation, two timers | 3892 worker_id, _timer.seconds()); |
3893 // XXX: need xxx/xxx type of notation, two timers | |
3891 } | 3894 } |
3892 assert(_collector->_markStack.isEmpty(), "Should have been emptied"); | 3895 assert(_collector->_markStack.isEmpty(), "Should have been emptied"); |
3893 assert(work_queue(i)->size() == 0, "Should have been emptied"); | 3896 assert(work_queue(worker_id)->size() == 0, "Should have been emptied"); |
3894 // Note that under the current task protocol, the | 3897 // Note that under the current task protocol, the |
3895 // following assertion is true even of the spaces | 3898 // following assertion is true even of the spaces |
3896 // expanded since the completion of the concurrent | 3899 // expanded since the completion of the concurrent |
3897 // marking. XXX This will likely change under a strict | 3900 // marking. XXX This will likely change under a strict |
3898 // ABORT semantics. | 3901 // ABORT semantics. |
3944 SequentialSubTasksDone* pst = sp->conc_par_seq_tasks(); | 3947 SequentialSubTasksDone* pst = sp->conc_par_seq_tasks(); |
3945 int n_tasks = pst->n_tasks(); | 3948 int n_tasks = pst->n_tasks(); |
3946 // We allow that there may be no tasks to do here because | 3949 // We allow that there may be no tasks to do here because |
3947 // we are restarting after a stack overflow. | 3950 // we are restarting after a stack overflow. |
3948 assert(pst->valid() || n_tasks == 0, "Uninitialized use?"); | 3951 assert(pst->valid() || n_tasks == 0, "Uninitialized use?"); |
3949 int nth_task = 0; | 3952 uint nth_task = 0; |
3950 | 3953 |
3951 HeapWord* aligned_start = sp->bottom(); | 3954 HeapWord* aligned_start = sp->bottom(); |
3952 if (sp->used_region().contains(_restart_addr)) { | 3955 if (sp->used_region().contains(_restart_addr)) { |
3953 // Align down to a card boundary for the start of 0th task | 3956 // Align down to a card boundary for the start of 0th task |
3954 // for this space. | 3957 // for this space. |
5073 OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); } | 5076 OopTaskQueue* work_queue(int i) { return task_queues()->queue(i); } |
5074 | 5077 |
5075 ParallelTaskTerminator* terminator() { return &_term; } | 5078 ParallelTaskTerminator* terminator() { return &_term; } |
5076 int n_workers() { return _n_workers; } | 5079 int n_workers() { return _n_workers; } |
5077 | 5080 |
5078 void work(int i); | 5081 void work(uint worker_id); |
5079 | 5082 |
5080 private: | 5083 private: |
5081 // Work method in support of parallel rescan ... of young gen spaces | 5084 // Work method in support of parallel rescan ... of young gen spaces |
5082 void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl, | 5085 void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl, |
5083 ContiguousSpace* space, | 5086 ContiguousSpace* space, |
5094 // work_queue(i) is passed to the closure | 5097 // work_queue(i) is passed to the closure |
5095 // Par_MarkRefsIntoAndScanClosure. The "i" parameter | 5098 // Par_MarkRefsIntoAndScanClosure. The "i" parameter |
5096 // also is passed to do_dirty_card_rescan_tasks() and to | 5099 // also is passed to do_dirty_card_rescan_tasks() and to |
5097 // do_work_steal() to select the i-th task_queue. | 5100 // do_work_steal() to select the i-th task_queue. |
5098 | 5101 |
5099 void CMSParRemarkTask::work(int i) { | 5102 void CMSParRemarkTask::work(uint worker_id) { |
5100 elapsedTimer _timer; | 5103 elapsedTimer _timer; |
5101 ResourceMark rm; | 5104 ResourceMark rm; |
5102 HandleMark hm; | 5105 HandleMark hm; |
5103 | 5106 |
5104 // ---------- rescan from roots -------------- | 5107 // ---------- rescan from roots -------------- |
5105 _timer.start(); | 5108 _timer.start(); |
5106 GenCollectedHeap* gch = GenCollectedHeap::heap(); | 5109 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
5107 Par_MarkRefsIntoAndScanClosure par_mrias_cl(_collector, | 5110 Par_MarkRefsIntoAndScanClosure par_mrias_cl(_collector, |
5108 _collector->_span, _collector->ref_processor(), | 5111 _collector->_span, _collector->ref_processor(), |
5109 &(_collector->_markBitMap), | 5112 &(_collector->_markBitMap), |
5110 work_queue(i), &(_collector->_revisitStack)); | 5113 work_queue(worker_id), &(_collector->_revisitStack)); |
5111 | 5114 |
5112 // Rescan young gen roots first since these are likely | 5115 // Rescan young gen roots first since these are likely |
5113 // coarsely partitioned and may, on that account, constitute | 5116 // coarsely partitioned and may, on that account, constitute |
5114 // the critical path; thus, it's best to start off that | 5117 // the critical path; thus, it's best to start off that |
5115 // work first. | 5118 // work first. |
5126 size_t sct = _collector->_survivor_chunk_index; | 5129 size_t sct = _collector->_survivor_chunk_index; |
5127 | 5130 |
5128 assert(ect <= _collector->_eden_chunk_capacity, "out of bounds"); | 5131 assert(ect <= _collector->_eden_chunk_capacity, "out of bounds"); |
5129 assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds"); | 5132 assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds"); |
5130 | 5133 |
5131 do_young_space_rescan(i, &par_mrias_cl, to_space, NULL, 0); | 5134 do_young_space_rescan(worker_id, &par_mrias_cl, to_space, NULL, 0); |
5132 do_young_space_rescan(i, &par_mrias_cl, from_space, sca, sct); | 5135 do_young_space_rescan(worker_id, &par_mrias_cl, from_space, sca, sct); |
5133 do_young_space_rescan(i, &par_mrias_cl, eden_space, eca, ect); | 5136 do_young_space_rescan(worker_id, &par_mrias_cl, eden_space, eca, ect); |
5134 | 5137 |
5135 _timer.stop(); | 5138 _timer.stop(); |
5136 if (PrintCMSStatistics != 0) { | 5139 if (PrintCMSStatistics != 0) { |
5137 gclog_or_tty->print_cr( | 5140 gclog_or_tty->print_cr( |
5138 "Finished young gen rescan work in %dth thread: %3.3f sec", | 5141 "Finished young gen rescan work in %dth thread: %3.3f sec", |
5139 i, _timer.seconds()); | 5142 worker_id, _timer.seconds()); |
5140 } | 5143 } |
5141 } | 5144 } |
5142 | 5145 |
5143 // ---------- remaining roots -------------- | 5146 // ---------- remaining roots -------------- |
5144 _timer.reset(); | 5147 _timer.reset(); |
5156 "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops"); | 5159 "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops"); |
5157 _timer.stop(); | 5160 _timer.stop(); |
5158 if (PrintCMSStatistics != 0) { | 5161 if (PrintCMSStatistics != 0) { |
5159 gclog_or_tty->print_cr( | 5162 gclog_or_tty->print_cr( |
5160 "Finished remaining root rescan work in %dth thread: %3.3f sec", | 5163 "Finished remaining root rescan work in %dth thread: %3.3f sec", |
5161 i, _timer.seconds()); | 5164 worker_id, _timer.seconds()); |
5162 } | 5165 } |
5163 | 5166 |
5164 // ---------- rescan dirty cards ------------ | 5167 // ---------- rescan dirty cards ------------ |
5165 _timer.reset(); | 5168 _timer.reset(); |
5166 _timer.start(); | 5169 _timer.start(); |
5167 | 5170 |
5168 // Do the rescan tasks for each of the two spaces | 5171 // Do the rescan tasks for each of the two spaces |
5169 // (cms_space and perm_space) in turn. | 5172 // (cms_space and perm_space) in turn. |
5170 // "i" is passed to select the "i-th" task_queue | 5173 // "worker_id" is passed to select the task_queue for "worker_id" |
5171 do_dirty_card_rescan_tasks(_cms_space, i, &par_mrias_cl); | 5174 do_dirty_card_rescan_tasks(_cms_space, worker_id, &par_mrias_cl); |
5172 do_dirty_card_rescan_tasks(_perm_space, i, &par_mrias_cl); | 5175 do_dirty_card_rescan_tasks(_perm_space, worker_id, &par_mrias_cl); |
5173 _timer.stop(); | 5176 _timer.stop(); |
5174 if (PrintCMSStatistics != 0) { | 5177 if (PrintCMSStatistics != 0) { |
5175 gclog_or_tty->print_cr( | 5178 gclog_or_tty->print_cr( |
5176 "Finished dirty card rescan work in %dth thread: %3.3f sec", | 5179 "Finished dirty card rescan work in %dth thread: %3.3f sec", |
5177 i, _timer.seconds()); | 5180 worker_id, _timer.seconds()); |
5178 } | 5181 } |
5179 | 5182 |
5180 // ---------- steal work from other threads ... | 5183 // ---------- steal work from other threads ... |
5181 // ---------- ... and drain overflow list. | 5184 // ---------- ... and drain overflow list. |
5182 _timer.reset(); | 5185 _timer.reset(); |
5183 _timer.start(); | 5186 _timer.start(); |
5184 do_work_steal(i, &par_mrias_cl, _collector->hash_seed(i)); | 5187 do_work_steal(worker_id, &par_mrias_cl, _collector->hash_seed(worker_id)); |
5185 _timer.stop(); | 5188 _timer.stop(); |
5186 if (PrintCMSStatistics != 0) { | 5189 if (PrintCMSStatistics != 0) { |
5187 gclog_or_tty->print_cr( | 5190 gclog_or_tty->print_cr( |
5188 "Finished work stealing in %dth thread: %3.3f sec", | 5191 "Finished work stealing in %dth thread: %3.3f sec", |
5189 i, _timer.seconds()); | 5192 worker_id, _timer.seconds()); |
5190 } | 5193 } |
5191 } | 5194 } |
5192 | 5195 |
5193 // Note that parameter "i" is not used. | 5196 // Note that parameter "i" is not used. |
5194 void | 5197 void |
5205 HandleMark hm; | 5208 HandleMark hm; |
5206 | 5209 |
5207 SequentialSubTasksDone* pst = space->par_seq_tasks(); | 5210 SequentialSubTasksDone* pst = space->par_seq_tasks(); |
5208 assert(pst->valid(), "Uninitialized use?"); | 5211 assert(pst->valid(), "Uninitialized use?"); |
5209 | 5212 |
5210 int nth_task = 0; | 5213 uint nth_task = 0; |
5211 int n_tasks = pst->n_tasks(); | 5214 uint n_tasks = pst->n_tasks(); |
5212 | 5215 |
5213 HeapWord *start, *end; | 5216 HeapWord *start, *end; |
5214 while (!pst->is_task_claimed(/* reference */ nth_task)) { | 5217 while (!pst->is_task_claimed(/* reference */ nth_task)) { |
5215 // We claimed task # nth_task; compute its boundaries. | 5218 // We claimed task # nth_task; compute its boundaries. |
5216 if (chunk_top == 0) { // no samples were taken | 5219 if (chunk_top == 0) { // no samples were taken |
5218 start = space->bottom(); | 5221 start = space->bottom(); |
5219 end = space->top(); | 5222 end = space->top(); |
5220 } else if (nth_task == 0) { | 5223 } else if (nth_task == 0) { |
5221 start = space->bottom(); | 5224 start = space->bottom(); |
5222 end = chunk_array[nth_task]; | 5225 end = chunk_array[nth_task]; |
5223 } else if (nth_task < (jint)chunk_top) { | 5226 } else if (nth_task < (uint)chunk_top) { |
5224 assert(nth_task >= 1, "Control point invariant"); | 5227 assert(nth_task >= 1, "Control point invariant"); |
5225 start = chunk_array[nth_task - 1]; | 5228 start = chunk_array[nth_task - 1]; |
5226 end = chunk_array[nth_task]; | 5229 end = chunk_array[nth_task]; |
5227 } else { | 5230 } else { |
5228 assert(nth_task == (jint)chunk_top, "Control point invariant"); | 5231 assert(nth_task == (uint)chunk_top, "Control point invariant"); |
5229 start = chunk_array[chunk_top - 1]; | 5232 start = chunk_array[chunk_top - 1]; |
5230 end = space->top(); | 5233 end = space->top(); |
5231 } | 5234 } |
5232 MemRegion mr(start, end); | 5235 MemRegion mr(start, end); |
5233 // Verify that mr is in space | 5236 // Verify that mr is in space |
5286 greyRescanClosure(_collector, full_span, // entire span of interest | 5289 greyRescanClosure(_collector, full_span, // entire span of interest |
5287 sp, bm, work_q, rs, cl); | 5290 sp, bm, work_q, rs, cl); |
5288 | 5291 |
5289 SequentialSubTasksDone* pst = sp->conc_par_seq_tasks(); | 5292 SequentialSubTasksDone* pst = sp->conc_par_seq_tasks(); |
5290 assert(pst->valid(), "Uninitialized use?"); | 5293 assert(pst->valid(), "Uninitialized use?"); |
5291 int nth_task = 0; | 5294 uint nth_task = 0; |
5292 const int alignment = CardTableModRefBS::card_size * BitsPerWord; | 5295 const int alignment = CardTableModRefBS::card_size * BitsPerWord; |
5293 MemRegion span = sp->used_region(); | 5296 MemRegion span = sp->used_region(); |
5294 HeapWord* start_addr = span.start(); | 5297 HeapWord* start_addr = span.start(); |
5295 HeapWord* end_addr = (HeapWord*)round_to((intptr_t)span.end(), | 5298 HeapWord* end_addr = (HeapWord*)round_to((intptr_t)span.end(), |
5296 alignment); | 5299 alignment); |
5734 void do_work_steal(int i, | 5737 void do_work_steal(int i, |
5735 CMSParDrainMarkingStackClosure* drain, | 5738 CMSParDrainMarkingStackClosure* drain, |
5736 CMSParKeepAliveClosure* keep_alive, | 5739 CMSParKeepAliveClosure* keep_alive, |
5737 int* seed); | 5740 int* seed); |
5738 | 5741 |
5739 virtual void work(int i); | 5742 virtual void work(uint worker_id); |
5740 }; | 5743 }; |
5741 | 5744 |
5742 void CMSRefProcTaskProxy::work(int i) { | 5745 void CMSRefProcTaskProxy::work(uint worker_id) { |
5743 assert(_collector->_span.equals(_span), "Inconsistency in _span"); | 5746 assert(_collector->_span.equals(_span), "Inconsistency in _span"); |
5744 CMSParKeepAliveClosure par_keep_alive(_collector, _span, | 5747 CMSParKeepAliveClosure par_keep_alive(_collector, _span, |
5745 _mark_bit_map, | 5748 _mark_bit_map, |
5746 &_collector->_revisitStack, | 5749 &_collector->_revisitStack, |
5747 work_queue(i)); | 5750 work_queue(worker_id)); |
5748 CMSParDrainMarkingStackClosure par_drain_stack(_collector, _span, | 5751 CMSParDrainMarkingStackClosure par_drain_stack(_collector, _span, |
5749 _mark_bit_map, | 5752 _mark_bit_map, |
5750 &_collector->_revisitStack, | 5753 &_collector->_revisitStack, |
5751 work_queue(i)); | 5754 work_queue(worker_id)); |
5752 CMSIsAliveClosure is_alive_closure(_span, _mark_bit_map); | 5755 CMSIsAliveClosure is_alive_closure(_span, _mark_bit_map); |
5753 _task.work(i, is_alive_closure, par_keep_alive, par_drain_stack); | 5756 _task.work(worker_id, is_alive_closure, par_keep_alive, par_drain_stack); |
5754 if (_task.marks_oops_alive()) { | 5757 if (_task.marks_oops_alive()) { |
5755 do_work_steal(i, &par_drain_stack, &par_keep_alive, | 5758 do_work_steal(worker_id, &par_drain_stack, &par_keep_alive, |
5756 _collector->hash_seed(i)); | 5759 _collector->hash_seed(worker_id)); |
5757 } | 5760 } |
5758 assert(work_queue(i)->size() == 0, "work_queue should be empty"); | 5761 assert(work_queue(worker_id)->size() == 0, "work_queue should be empty"); |
5759 assert(_collector->_overflow_list == NULL, "non-empty _overflow_list"); | 5762 assert(_collector->_overflow_list == NULL, "non-empty _overflow_list"); |
5760 } | 5763 } |
5761 | 5764 |
5762 class CMSRefEnqueueTaskProxy: public AbstractGangTask { | 5765 class CMSRefEnqueueTaskProxy: public AbstractGangTask { |
5763 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; | 5766 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; |
5767 CMSRefEnqueueTaskProxy(EnqueueTask& task) | 5770 CMSRefEnqueueTaskProxy(EnqueueTask& task) |
5768 : AbstractGangTask("Enqueue reference objects in parallel"), | 5771 : AbstractGangTask("Enqueue reference objects in parallel"), |
5769 _task(task) | 5772 _task(task) |
5770 { } | 5773 { } |
5771 | 5774 |
5772 virtual void work(int i) | 5775 virtual void work(uint worker_id) |
5773 { | 5776 { |
5774 _task.work(i); | 5777 _task.work(worker_id); |
5775 } | 5778 } |
5776 }; | 5779 }; |
5777 | 5780 |
5778 CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector, | 5781 CMSParKeepAliveClosure::CMSParKeepAliveClosure(CMSCollector* collector, |
5779 MemRegion span, CMSBitMap* bit_map, CMSMarkStack* revisit_stack, | 5782 MemRegion span, CMSBitMap* bit_map, CMSMarkStack* revisit_stack, |