Mercurial > hg > graal-jvmci-8
comparison src/share/vm/classfile/classLoader.hpp @ 875:6a93908f268f
6857194: Add hotspot perf counters to aid class loading performance measurement
Summary: Add new jvmstat counters to measure detailed class loading time
Reviewed-by: acorn, kamg
author | mchung |
---|---|
date | Fri, 10 Jul 2009 11:10:00 -0700 |
parents | a61af66fc99e |
children | 89e0543e1737 |
comparison
equal
deleted
inserted
replaced
812:85d0690f7d12 | 875:6a93908f268f |
---|---|
147 | 147 |
148 // Performance counters | 148 // Performance counters |
149 static PerfCounter* _perf_accumulated_time; | 149 static PerfCounter* _perf_accumulated_time; |
150 static PerfCounter* _perf_classes_inited; | 150 static PerfCounter* _perf_classes_inited; |
151 static PerfCounter* _perf_class_init_time; | 151 static PerfCounter* _perf_class_init_time; |
152 static PerfCounter* _perf_class_init_selftime; | |
153 static PerfCounter* _perf_classes_verified; | |
152 static PerfCounter* _perf_class_verify_time; | 154 static PerfCounter* _perf_class_verify_time; |
155 static PerfCounter* _perf_class_verify_selftime; | |
153 static PerfCounter* _perf_classes_linked; | 156 static PerfCounter* _perf_classes_linked; |
154 static PerfCounter* _perf_class_link_time; | 157 static PerfCounter* _perf_class_link_time; |
158 static PerfCounter* _perf_class_link_selftime; | |
159 static PerfCounter* _perf_class_parse_time; | |
160 static PerfCounter* _perf_class_parse_selftime; | |
161 static PerfCounter* _perf_sys_class_lookup_time; | |
162 static PerfCounter* _perf_shared_classload_time; | |
163 static PerfCounter* _perf_sys_classload_time; | |
164 static PerfCounter* _perf_app_classload_time; | |
165 static PerfCounter* _perf_app_classload_selftime; | |
166 static PerfCounter* _perf_app_classload_count; | |
167 static PerfCounter* _perf_define_appclasses; | |
168 static PerfCounter* _perf_define_appclass_time; | |
169 static PerfCounter* _perf_define_appclass_selftime; | |
170 static PerfCounter* _perf_app_classfile_bytes_read; | |
171 static PerfCounter* _perf_sys_classfile_bytes_read; | |
155 | 172 |
156 static PerfCounter* _sync_systemLoaderLockContentionRate; | 173 static PerfCounter* _sync_systemLoaderLockContentionRate; |
157 static PerfCounter* _sync_nonSystemLoaderLockContentionRate; | 174 static PerfCounter* _sync_nonSystemLoaderLockContentionRate; |
158 static PerfCounter* _sync_JVMFindLoadedClassLockFreeCounter; | 175 static PerfCounter* _sync_JVMFindLoadedClassLockFreeCounter; |
159 static PerfCounter* _sync_JVMDefineClassLockFreeCounter; | 176 static PerfCounter* _sync_JVMDefineClassLockFreeCounter; |
194 static void update_class_path_entry_list(const char *path, | 211 static void update_class_path_entry_list(const char *path, |
195 bool check_for_duplicates); | 212 bool check_for_duplicates); |
196 static void print_bootclasspath(); | 213 static void print_bootclasspath(); |
197 | 214 |
198 // Timing | 215 // Timing |
199 static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; } | 216 static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; } |
200 static PerfCounter* perf_classes_inited() { return _perf_classes_inited; } | 217 static PerfCounter* perf_classes_inited() { return _perf_classes_inited; } |
201 static PerfCounter* perf_class_init_time() { return _perf_class_init_time; } | 218 static PerfCounter* perf_class_init_time() { return _perf_class_init_time; } |
202 static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; } | 219 static PerfCounter* perf_class_init_selftime() { return _perf_class_init_selftime; } |
203 static PerfCounter* perf_classes_linked() { return _perf_classes_linked; } | 220 static PerfCounter* perf_classes_verified() { return _perf_classes_verified; } |
204 static PerfCounter* perf_class_link_time() { return _perf_class_link_time; } | 221 static PerfCounter* perf_class_verify_time() { return _perf_class_verify_time; } |
222 static PerfCounter* perf_class_verify_selftime() { return _perf_class_verify_selftime; } | |
223 static PerfCounter* perf_classes_linked() { return _perf_classes_linked; } | |
224 static PerfCounter* perf_class_link_time() { return _perf_class_link_time; } | |
225 static PerfCounter* perf_class_link_selftime() { return _perf_class_link_selftime; } | |
226 static PerfCounter* perf_class_parse_time() { return _perf_class_parse_time; } | |
227 static PerfCounter* perf_class_parse_selftime() { return _perf_class_parse_selftime; } | |
228 static PerfCounter* perf_sys_class_lookup_time() { return _perf_sys_class_lookup_time; } | |
229 static PerfCounter* perf_shared_classload_time() { return _perf_shared_classload_time; } | |
230 static PerfCounter* perf_sys_classload_time() { return _perf_sys_classload_time; } | |
231 static PerfCounter* perf_app_classload_time() { return _perf_app_classload_time; } | |
232 static PerfCounter* perf_app_classload_selftime() { return _perf_app_classload_selftime; } | |
233 static PerfCounter* perf_app_classload_count() { return _perf_app_classload_count; } | |
234 static PerfCounter* perf_define_appclasses() { return _perf_define_appclasses; } | |
235 static PerfCounter* perf_define_appclass_time() { return _perf_define_appclass_time; } | |
236 static PerfCounter* perf_define_appclass_selftime() { return _perf_define_appclass_selftime; } | |
237 static PerfCounter* perf_app_classfile_bytes_read() { return _perf_app_classfile_bytes_read; } | |
238 static PerfCounter* perf_sys_classfile_bytes_read() { return _perf_sys_classfile_bytes_read; } | |
205 | 239 |
206 // Record how often system loader lock object is contended | 240 // Record how often system loader lock object is contended |
207 static PerfCounter* sync_systemLoaderLockContentionRate() { | 241 static PerfCounter* sync_systemLoaderLockContentionRate() { |
208 return _sync_systemLoaderLockContentionRate; | 242 return _sync_systemLoaderLockContentionRate; |
209 } | 243 } |
305 static void compile_the_world(); | 339 static void compile_the_world(); |
306 static void compile_the_world_in(char* name, Handle loader, TRAPS); | 340 static void compile_the_world_in(char* name, Handle loader, TRAPS); |
307 static int compile_the_world_counter() { return _compile_the_world_counter; } | 341 static int compile_the_world_counter() { return _compile_the_world_counter; } |
308 #endif //PRODUCT | 342 #endif //PRODUCT |
309 }; | 343 }; |
344 | |
345 // PerfClassTraceTime is used to measure time for class loading related events. | |
346 // This class tracks cumulative time and exclusive time for specific event types. | |
347 // During the execution of one event, other event types (e.g. class loading and | |
348 // resolution) as well as recursive calls of the same event type could happen. | |
349 // Only one elapsed timer (cumulative) and one thread-local self timer (exclusive) | |
350 // (i.e. only one event type) are active at a time even multiple PerfClassTraceTime | |
351 // instances have been created as multiple events are happening. | |
352 class PerfClassTraceTime { | |
353 public: | |
354 enum { | |
355 CLASS_LOAD = 0, | |
356 PARSE_CLASS = 1, | |
357 CLASS_LINK = 2, | |
358 CLASS_VERIFY = 3, | |
359 CLASS_CLINIT = 4, | |
360 DEFINE_CLASS = 5, | |
361 EVENT_TYPE_COUNT = 6 | |
362 }; | |
363 protected: | |
364 // _t tracks time from initialization to destruction of this timer instance | |
365 // including time for all other event types, and recursive calls of this type. | |
366 // When a timer is called recursively, the elapsedTimer _t would not be used. | |
367 elapsedTimer _t; | |
368 PerfLongCounter* _timep; | |
369 PerfLongCounter* _selftimep; | |
370 PerfLongCounter* _eventp; | |
371 // pointer to thread-local recursion counter and timer array | |
372 // The thread_local timers track cumulative time for specific event types | |
373 // exclusive of time for other event types, but including recursive calls | |
374 // of the same type. | |
375 int* _recursion_counters; | |
376 elapsedTimer* _timers; | |
377 int _event_type; | |
378 int _prev_active_event; | |
379 | |
380 public: | |
381 | |
382 inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */ | |
383 PerfLongCounter* selftimep, /* counter incremented with exclusive time */ | |
384 PerfLongCounter* eventp, /* event counter */ | |
385 int* recursion_counters, /* thread-local recursion counter array */ | |
386 elapsedTimer* timers, /* thread-local timer array */ | |
387 int type /* event type */ ) : | |
388 _timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) { | |
389 initialize(); | |
390 } | |
391 | |
392 inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */ | |
393 elapsedTimer* timers, /* thread-local timer array */ | |
394 int type /* event type */ ) : | |
395 _timep(timep), _selftimep(NULL), _eventp(NULL), _recursion_counters(NULL), _timers(timers), _event_type(type) { | |
396 initialize(); | |
397 } | |
398 | |
399 void initialize() { | |
400 if (!UsePerfData) return; | |
401 | |
402 if (_eventp != NULL) { | |
403 // increment the event counter | |
404 _eventp->inc(); | |
405 } | |
406 | |
407 // stop the current active thread-local timer to measure inclusive time | |
408 _prev_active_event = -1; | |
409 for (int i=0; i < EVENT_TYPE_COUNT; i++) { | |
410 if (_timers[i].is_active()) { | |
411 assert(_prev_active_event == -1, "should have only one active timer"); | |
412 _prev_active_event = i; | |
413 _timers[i].stop(); | |
414 } | |
415 } | |
416 | |
417 if (_recursion_counters == NULL || (_recursion_counters[_event_type])++ == 0) { | |
418 // start the inclusive timer if not recursively called | |
419 _t.start(); | |
420 } | |
421 | |
422 // start thread-local timer of the given event type | |
423 if (!_timers[_event_type].is_active()) { | |
424 _timers[_event_type].start(); | |
425 } | |
426 } | |
427 | |
428 inline void suspend() { _t.stop(); _timers[_event_type].stop(); } | |
429 inline void resume() { _t.start(); _timers[_event_type].start(); } | |
430 | |
431 ~PerfClassTraceTime() { | |
432 if (!UsePerfData) return; | |
433 | |
434 // stop the thread-local timer as the event completes | |
435 // and resume the thread-local timer of the event next on the stack | |
436 _timers[_event_type].stop(); | |
437 jlong selftime = _timers[_event_type].ticks(); | |
438 | |
439 if (_prev_active_event >= 0) { | |
440 _timers[_prev_active_event].start(); | |
441 } | |
442 | |
443 if (_recursion_counters != NULL && --(_recursion_counters[_event_type]) > 0) return; | |
444 | |
445 // increment the counters only on the leaf call | |
446 _t.stop(); | |
447 _timep->inc(_t.ticks()); | |
448 if (_selftimep != NULL) { | |
449 _selftimep->inc(selftime); | |
450 } | |
451 // add all class loading related event selftime to the accumulated time counter | |
452 ClassLoader::perf_accumulated_time()->inc(selftime); | |
453 | |
454 // reset the timer | |
455 _timers[_event_type].reset(); | |
456 } | |
457 }; | |
458 |