hotspot/src/share/vm/classfile/classLoader.hpp
changeset 7910 135031ddb2bb
parent 7397 5b173b4ca846
child 8076 96d498ec7ae1
equal deleted inserted replaced
7909:96e81d4e789c 7910:135031ddb2bb
   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