comparison src/share/vm/classfile/classLoader.hpp @ 2139:75efcee5ac47

6966589: hs16-b08 causes java.lang.StackOverflowError Reviewed-by: mchung, dholmes, chrisphi
author minqi
date Thu, 07 Oct 2010 13:49:40 -0700
parents f95d63e2154a
children 3582bf76420e
comparison
equal deleted inserted replaced
2138:0915f9be781c 2139:75efcee5ac47
354 // resolution) as well as recursive calls of the same event type could happen. 354 // resolution) as well as recursive calls of the same event type could happen.
355 // Only one elapsed timer (cumulative) and one thread-local self timer (exclusive) 355 // Only one elapsed timer (cumulative) and one thread-local self timer (exclusive)
356 // (i.e. only one event type) are active at a time even multiple PerfClassTraceTime 356 // (i.e. only one event type) are active at a time even multiple PerfClassTraceTime
357 // instances have been created as multiple events are happening. 357 // instances have been created as multiple events are happening.
358 class PerfClassTraceTime { 358 class PerfClassTraceTime {
359 public: 359 public:
360 enum { 360 enum {
361 CLASS_LOAD = 0, 361 CLASS_LOAD = 0,
362 PARSE_CLASS = 1, 362 PARSE_CLASS = 1,
363 CLASS_LINK = 2, 363 CLASS_LINK = 2,
364 CLASS_VERIFY = 3, 364 CLASS_VERIFY = 3,
365 CLASS_CLINIT = 4, 365 CLASS_CLINIT = 4,
366 DEFINE_CLASS = 5, 366 DEFINE_CLASS = 5,
367 EVENT_TYPE_COUNT = 6 367 EVENT_TYPE_COUNT = 6
368 }; 368 };
369 protected: 369 protected:
370 // _t tracks time from initialization to destruction of this timer instance 370 // _t tracks time from initialization to destruction of this timer instance
371 // including time for all other event types, and recursive calls of this type. 371 // including time for all other event types, and recursive calls of this type.
372 // When a timer is called recursively, the elapsedTimer _t would not be used. 372 // When a timer is called recursively, the elapsedTimer _t would not be used.
373 elapsedTimer _t; 373 elapsedTimer _t;
374 PerfLongCounter* _timep; 374 PerfLongCounter* _timep;
375 PerfLongCounter* _selftimep; 375 PerfLongCounter* _selftimep;
376 PerfLongCounter* _eventp; 376 PerfLongCounter* _eventp;
377 // pointer to thread-local recursion counter and timer array 377 // pointer to thread-local recursion counter and timer array
378 // The thread_local timers track cumulative time for specific event types 378 // The thread_local timers track cumulative time for specific event types
379 // exclusive of time for other event types, but including recursive calls 379 // exclusive of time for other event types, but including recursive calls
380 // of the same type. 380 // of the same type.
381 int* _recursion_counters; 381 int* _recursion_counters;
382 elapsedTimer* _timers; 382 elapsedTimer* _timers;
383 int _event_type; 383 int _event_type;
384 int _prev_active_event; 384 int _prev_active_event;
385 385
386 public: 386 public:
387 387
388 inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */ 388 inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */
389 PerfLongCounter* selftimep, /* counter incremented with exclusive time */ 389 PerfLongCounter* selftimep, /* counter incremented with exclusive time */
390 PerfLongCounter* eventp, /* event counter */ 390 PerfLongCounter* eventp, /* event counter */
391 int* recursion_counters, /* thread-local recursion counter array */ 391 int* recursion_counters, /* thread-local recursion counter array */
392 elapsedTimer* timers, /* thread-local timer array */ 392 elapsedTimer* timers, /* thread-local timer array */
393 int type /* event type */ ) : 393 int type /* event type */ ) :
394 _timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) { 394 _timep(timep), _selftimep(selftimep), _eventp(eventp), _recursion_counters(recursion_counters), _timers(timers), _event_type(type) {
395 initialize(); 395 initialize();
396 } 396 }
397 397
398 inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */ 398 inline PerfClassTraceTime(PerfLongCounter* timep, /* counter incremented with inclusive time */
399 elapsedTimer* timers, /* thread-local timer array */ 399 elapsedTimer* timers, /* thread-local timer array */
400 int type /* event type */ ) : 400 int type /* event type */ ) :
401 _timep(timep), _selftimep(NULL), _eventp(NULL), _recursion_counters(NULL), _timers(timers), _event_type(type) { 401 _timep(timep), _selftimep(NULL), _eventp(NULL), _recursion_counters(NULL), _timers(timers), _event_type(type) {
402 initialize(); 402 initialize();
403 } 403 }
404 404
405 void initialize() { 405 inline void suspend() { _t.stop(); _timers[_event_type].stop(); }
406 if (!UsePerfData) return; 406 inline void resume() { _t.start(); _timers[_event_type].start(); }
407 407
408 if (_eventp != NULL) { 408 ~PerfClassTraceTime();
409 // increment the event counter 409 void initialize();
410 _eventp->inc(); 410 };
411 }
412
413 // stop the current active thread-local timer to measure inclusive time
414 _prev_active_event = -1;
415 for (int i=0; i < EVENT_TYPE_COUNT; i++) {
416 if (_timers[i].is_active()) {
417 assert(_prev_active_event == -1, "should have only one active timer");
418 _prev_active_event = i;
419 _timers[i].stop();
420 }
421 }
422
423 if (_recursion_counters == NULL || (_recursion_counters[_event_type])++ == 0) {
424 // start the inclusive timer if not recursively called
425 _t.start();
426 }
427
428 // start thread-local timer of the given event type
429 if (!_timers[_event_type].is_active()) {
430 _timers[_event_type].start();
431 }
432 }
433
434 inline void suspend() { _t.stop(); _timers[_event_type].stop(); }
435 inline void resume() { _t.start(); _timers[_event_type].start(); }
436
437 ~PerfClassTraceTime() {
438 if (!UsePerfData) return;
439
440 // stop the thread-local timer as the event completes
441 // and resume the thread-local timer of the event next on the stack
442 _timers[_event_type].stop();
443 jlong selftime = _timers[_event_type].ticks();
444
445 if (_prev_active_event >= 0) {
446 _timers[_prev_active_event].start();
447 }
448
449 if (_recursion_counters != NULL && --(_recursion_counters[_event_type]) > 0) return;
450
451 // increment the counters only on the leaf call
452 _t.stop();
453 _timep->inc(_t.ticks());
454 if (_selftimep != NULL) {
455 _selftimep->inc(selftime);
456 }
457 // add all class loading related event selftime to the accumulated time counter
458 ClassLoader::perf_accumulated_time()->inc(selftime);
459
460 // reset the timer
461 _timers[_event_type].reset();
462 }
463 };
464
465 411
466 #endif // SHARE_VM_CLASSFILE_CLASSLOADER_HPP 412 #endif // SHARE_VM_CLASSFILE_CLASSLOADER_HPP