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 |