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_UNINITILAIZED(phase) \ 110 assert(_gc_par_phases[phase]->get(i) == uninitialized, "Phase " #phase " reported for thread that was not started"); 111 112 #define ADD_WORKER_KNOWN_TIME(phase) \ 113 do { \ 114 double value = _gc_par_phases[phase]->get(i); \ 115 if (value != uninitialized) { \ 116 worker_known_time += value; \ 117 } \ 118 } while(false) 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 = _gc_par_phases[GCWorkerStart]->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 // Make sure all slots are uninitialized since this thread did not seem to have been started 129 ASSERT_PHASE_UNINITILAIZED(GCWorkerEnd); 130 ASSERT_PHASE_UNINITILAIZED(ExtRootScan); 131 ASSERT_PHASE_UNINITILAIZED(SATBFiltering); 132 ASSERT_PHASE_UNINITILAIZED(UpdateRS); 133 ASSERT_PHASE_UNINITILAIZED(ScanRS); 134 ASSERT_PHASE_UNINITILAIZED(CodeRoots); 135 ASSERT_PHASE_UNINITILAIZED(ObjCopy); 136 ASSERT_PHASE_UNINITILAIZED(Termination); 137 } else { 138 assert(_gc_par_phases[GCWorkerEnd]->get(i) != _gc_par_phases[GCWorkerEnd]->uninitialized(), "Worker started but not ended."); 139 double worker_time = _gc_par_phases[GCWorkerEnd]->get(i) - _gc_par_phases[GCWorkerStart]->get(i); 140 record_time_secs(GCWorkerTotal, i , worker_time); 141 142 double worker_known_time = 0.0; 143 ADD_WORKER_KNOWN_TIME(ExtRootScan); 144 ADD_WORKER_KNOWN_TIME(SATBFiltering); 145 ADD_WORKER_KNOWN_TIME(UpdateRS); 146 ADD_WORKER_KNOWN_TIME(ScanRS); 147 ADD_WORKER_KNOWN_TIME(CodeRoots); 148 ADD_WORKER_KNOWN_TIME(ObjCopy); 149 ADD_WORKER_KNOWN_TIME(Termination); 150 151 record_time_secs(Other, i, worker_time - worker_known_time); 152 } 153 } 154 } 155 156 #undef ADD_WORKER_KNOWN_TIME 157 #undef ASSERT_PHASE_UNINITILAIZED 158 159 // record the time a phase took in seconds 160 void G1GCPhaseTimes::record_time_secs(GCParPhases phase, uint worker_i, double secs) { 161 _gc_par_phases[phase]->set(worker_i, secs); 162 } 163 164 // add a number of seconds to a phase 165 void G1GCPhaseTimes::add_time_secs(GCParPhases phase, uint worker_i, double secs) { 166 _gc_par_phases[phase]->add(worker_i, secs); 167 } 168 169 void G1GCPhaseTimes::record_thread_work_item(GCParPhases phase, uint worker_i, size_t count) { 170 _gc_par_phases[phase]->set_thread_work_item(worker_i, count); 171 } 172 173 // return the average time for a phase in milliseconds 174 double G1GCPhaseTimes::average_time_ms(GCParPhases phase) { 175 return _gc_par_phases[phase]->average() * 1000.0; 176 } 177 | 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 |