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,