hotspot/src/share/vm/gc_implementation/shared/gcOverheadReporter.cpp
changeset 3692 9530a85b334c
parent 3690 dba50b88bd50
parent 3691 c84b8483cd2c
child 3693 af387bf37e8d
equal deleted inserted replaced
3690:dba50b88bd50 3692:9530a85b334c
     1 /*
       
     2  * Copyright 2001-2007 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  *
       
    23  */
       
    24 
       
    25 # include "incls/_precompiled.incl"
       
    26 # include "incls/_gcOverheadReporter.cpp.incl"
       
    27 
       
    28 class COReportingThread : public ConcurrentGCThread {
       
    29 private:
       
    30   GCOverheadReporter* _reporter;
       
    31 
       
    32 public:
       
    33   COReportingThread(GCOverheadReporter* reporter) : _reporter(reporter) {
       
    34     guarantee( _reporter != NULL, "precondition" );
       
    35     create_and_start();
       
    36   }
       
    37 
       
    38   virtual void run() {
       
    39     initialize_in_thread();
       
    40     wait_for_universe_init();
       
    41 
       
    42     int period_ms = GCOverheadReportingPeriodMS;
       
    43 
       
    44     while ( true ) {
       
    45       os::sleep(Thread::current(), period_ms, false);
       
    46 
       
    47       _sts.join();
       
    48       double now_sec = os::elapsedTime();
       
    49       _reporter->collect_and_record_conc_overhead(now_sec);
       
    50       _sts.leave();
       
    51     }
       
    52 
       
    53     terminate();
       
    54   }
       
    55 };
       
    56 
       
    57 GCOverheadReporter* GCOverheadReporter::_reporter = NULL;
       
    58 
       
    59 GCOverheadReporter::GCOverheadReporter(size_t group_num,
       
    60                                        const char* group_names[],
       
    61                                        size_t length)
       
    62     : _group_num(group_num), _prev_end_sec(0.0) {
       
    63   guarantee( 0 <= group_num && group_num <= MaxGCOverheadGroupNum,
       
    64              "precondition" );
       
    65 
       
    66   _base = NEW_C_HEAP_ARRAY(GCOverheadReporterEntry, length);
       
    67   _top  = _base + length;
       
    68   _curr = _base;
       
    69 
       
    70   for (size_t i = 0; i < group_num; ++i) {
       
    71     guarantee( group_names[i] != NULL, "precondition" );
       
    72     _group_names[i] = group_names[i];
       
    73   }
       
    74 }
       
    75 
       
    76 void
       
    77 GCOverheadReporter::add(double start_sec, double end_sec,
       
    78                         double* conc_overhead,
       
    79                         double stw_overhead) {
       
    80   assert( _curr <= _top, "invariant" );
       
    81 
       
    82   if (_curr == _top) {
       
    83     guarantee( false, "trace full" );
       
    84     return;
       
    85   }
       
    86 
       
    87   _curr->_start_sec       = start_sec;
       
    88   _curr->_end_sec         = end_sec;
       
    89   for (size_t i = 0; i < _group_num; ++i) {
       
    90     _curr->_conc_overhead[i] =
       
    91       (conc_overhead != NULL) ? conc_overhead[i] : 0.0;
       
    92   }
       
    93   _curr->_stw_overhead    = stw_overhead;
       
    94 
       
    95   ++_curr;
       
    96 }
       
    97 
       
    98 void
       
    99 GCOverheadReporter::collect_and_record_conc_overhead(double end_sec) {
       
   100   double start_sec = _prev_end_sec;
       
   101   guarantee( end_sec > start_sec, "invariant" );
       
   102 
       
   103   double conc_overhead[MaxGCOverheadGroupNum];
       
   104   COTracker::totalConcOverhead(end_sec, _group_num, conc_overhead);
       
   105   add_conc_overhead(start_sec, end_sec, conc_overhead);
       
   106   _prev_end_sec = end_sec;
       
   107 }
       
   108 
       
   109 void
       
   110 GCOverheadReporter::record_stw_start(double start_sec) {
       
   111   guarantee( start_sec > _prev_end_sec, "invariant" );
       
   112   collect_and_record_conc_overhead(start_sec);
       
   113 }
       
   114 
       
   115 void
       
   116 GCOverheadReporter::record_stw_end(double end_sec) {
       
   117   double start_sec = _prev_end_sec;
       
   118   COTracker::updateAllForSTW(start_sec, end_sec);
       
   119   add_stw_overhead(start_sec, end_sec, 1.0);
       
   120 
       
   121   _prev_end_sec = end_sec;
       
   122 }
       
   123 
       
   124 void
       
   125 GCOverheadReporter::print() const {
       
   126   tty->print_cr("");
       
   127   tty->print_cr("GC Overhead (%d entries)", _curr - _base);
       
   128   tty->print_cr("");
       
   129   GCOverheadReporterEntry* curr = _base;
       
   130   while (curr < _curr) {
       
   131     double total = curr->_stw_overhead;
       
   132     for (size_t i = 0; i < _group_num; ++i)
       
   133       total += curr->_conc_overhead[i];
       
   134 
       
   135     tty->print("OVERHEAD %12.8lf %12.8lf ",
       
   136                curr->_start_sec, curr->_end_sec);
       
   137 
       
   138     for (size_t i = 0; i < _group_num; ++i)
       
   139       tty->print("%s %12.8lf ", _group_names[i], curr->_conc_overhead[i]);
       
   140 
       
   141     tty->print_cr("STW %12.8lf TOT %12.8lf", curr->_stw_overhead, total);
       
   142     ++curr;
       
   143   }
       
   144   tty->print_cr("");
       
   145 }
       
   146 
       
   147 // statics
       
   148 
       
   149 void
       
   150 GCOverheadReporter::initGCOverheadReporter(size_t group_num,
       
   151                                            const char* group_names[]) {
       
   152   guarantee( _reporter == NULL, "should only be called once" );
       
   153   guarantee( 0 <= group_num && group_num <= MaxGCOverheadGroupNum,
       
   154              "precondition" );
       
   155   guarantee( group_names != NULL, "pre-condition" );
       
   156 
       
   157   if (GCOverheadReporting) {
       
   158     _reporter = new GCOverheadReporter(group_num, group_names);
       
   159     new COReportingThread(_reporter);
       
   160   }
       
   161 }
       
   162 
       
   163 void
       
   164 GCOverheadReporter::recordSTWStart(double start_sec) {
       
   165   if (_reporter != NULL)
       
   166     _reporter->record_stw_start(start_sec);
       
   167 }
       
   168 
       
   169 void
       
   170 GCOverheadReporter::recordSTWEnd(double end_sec) {
       
   171   if (_reporter != NULL)
       
   172     _reporter->record_stw_end(end_sec);
       
   173 }
       
   174 
       
   175 void
       
   176 GCOverheadReporter::printGCOverhead() {
       
   177   if (_reporter != NULL)
       
   178     _reporter->print();
       
   179 }