232 } 233 234 for (uint i = 0; i < _length; i++) { 235 assert(_data[i] != WorkerDataArray<T>::uninitialized(), 236 err_msg("Invalid data for worker %u in '%s'", i, _title)); 237 } 238 if (_thread_work_items != NULL) { 239 _thread_work_items->verify(); 240 } 241 } 242 243 #endif 244 245 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) : 246 _max_gc_threads(max_gc_threads) 247 { 248 assert(max_gc_threads > 0, "Must have some GC threads"); 249 250 _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start (ms)", false, G1Log::LevelFiner, 2); 251 _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning (ms)", true, G1Log::LevelFiner, 2); 252 _gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering (ms)", true, G1Log::LevelFiner, 2); 253 _gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS (ms)", true, G1Log::LevelFiner, 2); 254 _gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS (ms)", true, G1Log::LevelFiner, 2); 255 _gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scanning (ms)", true, G1Log::LevelFiner, 2); 256 _gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy (ms)", true, G1Log::LevelFiner, 2); 257 _gc_par_phases[Termination] = new WorkerDataArray<double>(max_gc_threads, "Termination (ms)", true, G1Log::LevelFiner, 2); 258 _gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Total (ms)", true, G1Log::LevelFiner, 2); 259 _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End (ms)", false, G1Log::LevelFiner, 2); 260 _gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other (ms)", true, G1Log::LevelFiner, 2); 261 262 _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers", true, G1Log::LevelFiner, 3); 263 _gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_processed_buffers); 264 265 _termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts", true, G1Log::LevelFinest, 3); 266 _gc_par_phases[Termination]->link_thread_work_items(_termination_attempts); 267 268 _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup (ms)", true, G1Log::LevelFiner, 2); 269 _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup (ms)", true, G1Log::LevelFiner, 2); 270 271 _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty", true, G1Log::LevelFinest, 3); 272 _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards", true, G1Log::LevelFinest, 3); 273 _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards); 274 } 275 276 void G1GCPhaseTimes::note_gc_start(uint active_gc_threads, bool mark_in_progress) { 277 assert(active_gc_threads > 0, "The number of threads must be > 0"); 278 assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max number of threads"); 279 _active_gc_threads = active_gc_threads; 280 281 for (int i = 0; i < GCParPhasesSentinel; i++) { 282 _gc_par_phases[i]->reset(); 283 } 284 285 _gc_par_phases[SATBFiltering]->set_enabled(mark_in_progress); 286 287 _gc_par_phases[StringDedupQueueFixup]->set_enabled(G1StringDedup::is_enabled()); 288 _gc_par_phases[StringDedupTableFixup]->set_enabled(G1StringDedup::is_enabled()); 289 } 290 291 void G1GCPhaseTimes::note_gc_end() { 292 for (uint i = 0; i < _active_gc_threads; i++) { 293 double worker_time = _gc_par_phases[GCWorkerEnd]->get(i) - _gc_par_phases[GCWorkerStart]->get(i); 294 record_time_secs(GCWorkerTotal, i , worker_time); 295 296 double worker_known_time = 297 _gc_par_phases[ExtRootScan]->get(i) + 298 _gc_par_phases[SATBFiltering]->get(i) + 299 _gc_par_phases[UpdateRS]->get(i) + 300 _gc_par_phases[ScanRS]->get(i) + 301 _gc_par_phases[CodeRoots]->get(i) + 302 _gc_par_phases[ObjCopy]->get(i) + 303 _gc_par_phases[Termination]->get(i); 304 305 record_time_secs(Other, i, worker_time - worker_known_time); | 232 } 233 234 for (uint i = 0; i < _length; i++) { 235 assert(_data[i] != WorkerDataArray<T>::uninitialized(), 236 err_msg("Invalid data for worker %u in '%s'", i, _title)); 237 } 238 if (_thread_work_items != NULL) { 239 _thread_work_items->verify(); 240 } 241 } 242 243 #endif 244 245 G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) : 246 _max_gc_threads(max_gc_threads) 247 { 248 assert(max_gc_threads > 0, "Must have some GC threads"); 249 250 _gc_par_phases[GCWorkerStart] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Start (ms)", false, G1Log::LevelFiner, 2); 251 _gc_par_phases[ExtRootScan] = new WorkerDataArray<double>(max_gc_threads, "Ext Root Scanning (ms)", true, G1Log::LevelFiner, 2); 252 253 // Root scanning phases 254 _gc_par_phases[ThreadRoots] = new WorkerDataArray<double>(max_gc_threads, "Thread Roots (ms)", true, G1Log::LevelFinest, 3); 255 _gc_par_phases[StringTableRoots] = new WorkerDataArray<double>(max_gc_threads, "StringTable Roots (ms)", true, G1Log::LevelFinest, 3); 256 _gc_par_phases[UniverseRoots] = new WorkerDataArray<double>(max_gc_threads, "Universe Roots (ms)", true, G1Log::LevelFinest, 3); 257 _gc_par_phases[JNIRoots] = new WorkerDataArray<double>(max_gc_threads, "JNI Handles Roots (ms)", true, G1Log::LevelFinest, 3); 258 _gc_par_phases[ObjectSynchronizerRoots] = new WorkerDataArray<double>(max_gc_threads, "ObjectSynchronizer Roots (ms)", true, G1Log::LevelFinest, 3); 259 _gc_par_phases[FlatProfilerRoots] = new WorkerDataArray<double>(max_gc_threads, "FlatProfiler Roots (ms)", true, G1Log::LevelFinest, 3); 260 _gc_par_phases[ManagementRoots] = new WorkerDataArray<double>(max_gc_threads, "Management Roots (ms)", true, G1Log::LevelFinest, 3); 261 _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots (ms)", true, G1Log::LevelFinest, 3); 262 _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms)", true, G1Log::LevelFinest, 3); 263 _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms)", true, G1Log::LevelFinest, 3); 264 _gc_par_phases[CodeCacheRoots] = new WorkerDataArray<double>(max_gc_threads, "CodeCache Roots (ms)", true, G1Log::LevelFinest, 3); 265 _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms)", true, G1Log::LevelFinest, 3); 266 _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms)", true, G1Log::LevelFinest, 3); 267 _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms)", true, G1Log::LevelFinest, 3); 268 _gc_par_phases[SATBFiltering] = new WorkerDataArray<double>(max_gc_threads, "SATB Filtering (ms)", true, G1Log::LevelFinest, 3); 269 270 _gc_par_phases[UpdateRS] = new WorkerDataArray<double>(max_gc_threads, "Update RS (ms)", true, G1Log::LevelFiner, 2); 271 _gc_par_phases[ScanRS] = new WorkerDataArray<double>(max_gc_threads, "Scan RS (ms)", true, G1Log::LevelFiner, 2); 272 _gc_par_phases[CodeRoots] = new WorkerDataArray<double>(max_gc_threads, "Code Root Scanning (ms)", true, G1Log::LevelFiner, 2); 273 _gc_par_phases[ObjCopy] = new WorkerDataArray<double>(max_gc_threads, "Object Copy (ms)", true, G1Log::LevelFiner, 2); 274 _gc_par_phases[Termination] = new WorkerDataArray<double>(max_gc_threads, "Termination (ms)", true, G1Log::LevelFiner, 2); 275 _gc_par_phases[GCWorkerTotal] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Total (ms)", true, G1Log::LevelFiner, 2); 276 _gc_par_phases[GCWorkerEnd] = new WorkerDataArray<double>(max_gc_threads, "GC Worker End (ms)", false, G1Log::LevelFiner, 2); 277 _gc_par_phases[Other] = new WorkerDataArray<double>(max_gc_threads, "GC Worker Other (ms)", true, G1Log::LevelFiner, 2); 278 279 _update_rs_processed_buffers = new WorkerDataArray<size_t>(max_gc_threads, "Processed Buffers", true, G1Log::LevelFiner, 3); 280 _gc_par_phases[UpdateRS]->link_thread_work_items(_update_rs_processed_buffers); 281 282 _termination_attempts = new WorkerDataArray<size_t>(max_gc_threads, "Termination Attempts", true, G1Log::LevelFinest, 3); 283 _gc_par_phases[Termination]->link_thread_work_items(_termination_attempts); 284 285 _gc_par_phases[StringDedupQueueFixup] = new WorkerDataArray<double>(max_gc_threads, "Queue Fixup (ms)", true, G1Log::LevelFiner, 2); 286 _gc_par_phases[StringDedupTableFixup] = new WorkerDataArray<double>(max_gc_threads, "Table Fixup (ms)", true, G1Log::LevelFiner, 2); 287 288 _gc_par_phases[RedirtyCards] = new WorkerDataArray<double>(max_gc_threads, "Parallel Redirty", true, G1Log::LevelFinest, 3); 289 _redirtied_cards = new WorkerDataArray<size_t>(max_gc_threads, "Redirtied Cards", true, G1Log::LevelFinest, 3); 290 _gc_par_phases[RedirtyCards]->link_thread_work_items(_redirtied_cards); 291 } 292 293 void G1GCPhaseTimes::note_gc_start(uint active_gc_threads, bool mark_in_progress) { 294 assert(active_gc_threads > 0, "The number of threads must be > 0"); 295 assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max number of threads"); 296 _active_gc_threads = active_gc_threads; 297 298 for (int i = 0; i < GCParPhasesSentinel; i++) { 299 _gc_par_phases[i]->reset(); 300 } 301 302 _gc_par_phases[StringDedupQueueFixup]->set_enabled(G1StringDedup::is_enabled()); 303 _gc_par_phases[StringDedupTableFixup]->set_enabled(G1StringDedup::is_enabled()); 304 } 305 306 void G1GCPhaseTimes::note_gc_end() { 307 for (uint i = 0; i < _active_gc_threads; i++) { 308 double worker_time = _gc_par_phases[GCWorkerEnd]->get(i) - _gc_par_phases[GCWorkerStart]->get(i); 309 record_time_secs(GCWorkerTotal, i , worker_time); 310 311 double worker_known_time = 312 _gc_par_phases[ExtRootScan]->get(i) + 313 _gc_par_phases[SATBFiltering]->get(i) + 314 _gc_par_phases[UpdateRS]->get(i) + 315 _gc_par_phases[ScanRS]->get(i) + 316 _gc_par_phases[CodeRoots]->get(i) + 317 _gc_par_phases[ObjCopy]->get(i) + 318 _gc_par_phases[Termination]->get(i); 319 320 record_time_secs(Other, i, worker_time - worker_known_time); |