89 90 _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty (ms):"); 91 _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards:"); 92 _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards); 93 94 _gc_par_phases[PreserveCMReferents] = new WorkerDataArray<double>(max_gc_threads, "Parallel Preserve CM Refs (ms):"); 95 } 96 97 void G1GCPhaseTimes::note_gc_start() { 98 _gc_start_counter = os::elapsed_counter(); 99 _cur_expand_heap_time_ms = 0.0; 100 _external_accounted_time_ms = 0.0; 101 102 for (int i = 0; i < GCParPhasesSentinel; i++) { 103 if (_gc_par_phases[i] != NULL) { 104 _gc_par_phases[i]->reset(); 105 } 106 } 107 } 108 109 #define ASSERT_PHASE_UNINITILIAZED(phase) \ 110 assert(_gc_par_phases[phase]->get(i) == uninitialized, "Phase " #phase " reported for thread that was not started"); 111 112 double G1GCPhaseTimes::worker_time(GCParPhases phase, uint worker) { 113 double value = _gc_par_phases[phase]->get(worker); 114 if (value != WorkerDataArray<double>::uninitialized()) { 115 return value; 116 } 117 return 0.0; 118 } 119 120 void G1GCPhaseTimes::note_gc_end() { 121 _gc_pause_time_ms = TimeHelper::counter_to_millis(os::elapsed_counter() - _gc_start_counter); 122 123 double uninitialized = WorkerDataArray<double>::uninitialized(); 124 125 for (uint i = 0; i < _max_gc_threads; i++) { 126 double worker_start = _gc_par_phases[GCWorkerStart]->get(i); 127 if (worker_start != uninitialized) { 128 assert(_gc_par_phases[GCWorkerEnd]->get(i) != uninitialized, "Worker started but not ended."); 129 double total_worker_time = _gc_par_phases[GCWorkerEnd]->get(i) - _gc_par_phases[GCWorkerStart]->get(i); 130 record_time_secs(GCWorkerTotal, i , total_worker_time); 131 132 double worker_known_time = 133 worker_time(ExtRootScan, i) 134 + worker_time(SATBFiltering, i) 135 + worker_time(UpdateRS, i) 136 + worker_time(ScanRS, i) 137 + worker_time(CodeRoots, i) 138 + worker_time(ObjCopy, i) 139 + worker_time(Termination, i); 140 141 record_time_secs(Other, i, total_worker_time - worker_known_time); 142 } else { 143 // Make sure all slots are uninitialized since this thread did not seem to have been started 144 ASSERT_PHASE_UNINITILIAZED(GCWorkerEnd); 145 ASSERT_PHASE_UNINITILIAZED(ExtRootScan); 146 ASSERT_PHASE_UNINITILIAZED(SATBFiltering); 147 ASSERT_PHASE_UNINITILIAZED(UpdateRS); 148 ASSERT_PHASE_UNINITILIAZED(ScanRS); 149 ASSERT_PHASE_UNINITILIAZED(CodeRoots); 150 ASSERT_PHASE_UNINITILIAZED(ObjCopy); 151 ASSERT_PHASE_UNINITILIAZED(Termination); 152 } 153 } 154 } 155 156 #undef ASSERT_PHASE_UNINITILIAZED 157 158 // record the time a phase took in seconds 159 void G1GCPhaseTimes::record_time_secs(GCParPhases phase, uint worker_i, double secs) { 160 _gc_par_phases[phase]->set(worker_i, secs); 161 } 162 163 // add a number of seconds to a phase 164 void G1GCPhaseTimes::add_time_secs(GCParPhases phase, uint worker_i, double secs) { 165 _gc_par_phases[phase]->add(worker_i, secs); 166 } 167 168 void G1GCPhaseTimes::record_thread_work_item(GCParPhases phase, uint worker_i, size_t count) { 169 _gc_par_phases[phase]->set_thread_work_item(worker_i, count); 170 } 171 172 // return the average time for a phase in milliseconds 173 double G1GCPhaseTimes::average_time_ms(GCParPhases phase) { 174 return _gc_par_phases[phase]->average() * 1000.0; 175 } 176 | 89 90 _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty (ms):"); 91 _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards:"); 92 _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards); 93 94 _gc_par_phases[PreserveCMReferents] = new WorkerDataArray<double>(max_gc_threads, "Parallel Preserve CM Refs (ms):"); 95 } 96 97 void G1GCPhaseTimes::note_gc_start() { 98 _gc_start_counter = os::elapsed_counter(); 99 _cur_expand_heap_time_ms = 0.0; 100 _external_accounted_time_ms = 0.0; 101 102 for (int i = 0; i < GCParPhasesSentinel; i++) { 103 if (_gc_par_phases[i] != NULL) { 104 _gc_par_phases[i]->reset(); 105 } 106 } 107 } 108 109 #define ASSERT_PHASE_UNINITIALIZED(phase) \ 110 assert(_gc_par_phases[phase]->get(i) == uninitialized, "Phase " #phase " reported for thread that was not started"); 111 112 double G1GCPhaseTimes::worker_time(GCParPhases phase, uint worker) { 113 double value = _gc_par_phases[phase]->get(worker); 114 if (value != WorkerDataArray<double>::uninitialized()) { 115 return value; 116 } 117 return 0.0; 118 } 119 120 void G1GCPhaseTimes::note_gc_end() { 121 _gc_pause_time_ms = TimeHelper::counter_to_millis(os::elapsed_counter() - _gc_start_counter); 122 123 double uninitialized = WorkerDataArray<double>::uninitialized(); 124 125 for (uint i = 0; i < _max_gc_threads; i++) { 126 double worker_start = _gc_par_phases[GCWorkerStart]->get(i); 127 if (worker_start != uninitialized) { 128 assert(_gc_par_phases[GCWorkerEnd]->get(i) != uninitialized, "Worker started but not ended."); 129 double total_worker_time = _gc_par_phases[GCWorkerEnd]->get(i) - _gc_par_phases[GCWorkerStart]->get(i); 130 record_time_secs(GCWorkerTotal, i , total_worker_time); 131 132 double worker_known_time = 133 worker_time(ExtRootScan, i) 134 + worker_time(SATBFiltering, i) 135 + worker_time(UpdateRS, i) 136 + worker_time(ScanRS, i) 137 + worker_time(CodeRoots, i) 138 + worker_time(ObjCopy, i) 139 + worker_time(Termination, i); 140 141 record_time_secs(Other, i, total_worker_time - worker_known_time); 142 } else { 143 // Make sure all slots are uninitialized since this thread did not seem to have been started 144 ASSERT_PHASE_UNINITIALIZED(GCWorkerEnd); 145 ASSERT_PHASE_UNINITIALIZED(ExtRootScan); 146 ASSERT_PHASE_UNINITIALIZED(SATBFiltering); 147 ASSERT_PHASE_UNINITIALIZED(UpdateRS); 148 ASSERT_PHASE_UNINITIALIZED(ScanRS); 149 ASSERT_PHASE_UNINITIALIZED(CodeRoots); 150 ASSERT_PHASE_UNINITIALIZED(ObjCopy); 151 ASSERT_PHASE_UNINITIALIZED(Termination); 152 } 153 } 154 } 155 156 #undef ASSERT_PHASE_UNINITIALIZED 157 158 // record the time a phase took in seconds 159 void G1GCPhaseTimes::record_time_secs(GCParPhases phase, uint worker_i, double secs) { 160 _gc_par_phases[phase]->set(worker_i, secs); 161 } 162 163 // add a number of seconds to a phase 164 void G1GCPhaseTimes::add_time_secs(GCParPhases phase, uint worker_i, double secs) { 165 _gc_par_phases[phase]->add(worker_i, secs); 166 } 167 168 void G1GCPhaseTimes::record_thread_work_item(GCParPhases phase, uint worker_i, size_t count) { 169 _gc_par_phases[phase]->set_thread_work_item(worker_i, count); 170 } 171 172 // return the average time for a phase in milliseconds 173 double G1GCPhaseTimes::average_time_ms(GCParPhases phase) { 174 return _gc_par_phases[phase]->average() * 1000.0; 175 } 176 |