Mercurial > hg > graal-jvmci-8
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 |