Mercurial > hg > truffle
diff src/share/vm/gc_implementation/shared/gcOverheadReporter.cpp @ 342:37f87013dfd8
6711316: Open source the Garbage-First garbage collector
Summary: First mercurial integration of the code for the Garbage-First garbage collector.
Reviewed-by: apetrusenko, iveresov, jmasa, sgoldman, tonyp, ysr
author | ysr |
---|---|
date | Thu, 05 Jun 2008 15:57:56 -0700 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/gc_implementation/shared/gcOverheadReporter.cpp Thu Jun 05 15:57:56 2008 -0700 @@ -0,0 +1,179 @@ +/* + * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +# include "incls/_precompiled.incl" +# include "incls/_gcOverheadReporter.cpp.incl" + +class COReportingThread : public ConcurrentGCThread { +private: + GCOverheadReporter* _reporter; + +public: + COReportingThread(GCOverheadReporter* reporter) : _reporter(reporter) { + guarantee( _reporter != NULL, "precondition" ); + create_and_start(); + } + + virtual void run() { + initialize_in_thread(); + wait_for_universe_init(); + + int period_ms = GCOverheadReportingPeriodMS; + + while ( true ) { + os::sleep(Thread::current(), period_ms, false); + + _sts.join(); + double now_sec = os::elapsedTime(); + _reporter->collect_and_record_conc_overhead(now_sec); + _sts.leave(); + } + + terminate(); + } +}; + +GCOverheadReporter* GCOverheadReporter::_reporter = NULL; + +GCOverheadReporter::GCOverheadReporter(size_t group_num, + const char* group_names[], + size_t length) + : _group_num(group_num), _prev_end_sec(0.0) { + guarantee( 0 <= group_num && group_num <= MaxGCOverheadGroupNum, + "precondition" ); + + _base = NEW_C_HEAP_ARRAY(GCOverheadReporterEntry, length); + _top = _base + length; + _curr = _base; + + for (size_t i = 0; i < group_num; ++i) { + guarantee( group_names[i] != NULL, "precondition" ); + _group_names[i] = group_names[i]; + } +} + +void +GCOverheadReporter::add(double start_sec, double end_sec, + double* conc_overhead, + double stw_overhead) { + assert( _curr <= _top, "invariant" ); + + if (_curr == _top) { + guarantee( false, "trace full" ); + return; + } + + _curr->_start_sec = start_sec; + _curr->_end_sec = end_sec; + for (size_t i = 0; i < _group_num; ++i) { + _curr->_conc_overhead[i] = + (conc_overhead != NULL) ? conc_overhead[i] : 0.0; + } + _curr->_stw_overhead = stw_overhead; + + ++_curr; +} + +void +GCOverheadReporter::collect_and_record_conc_overhead(double end_sec) { + double start_sec = _prev_end_sec; + guarantee( end_sec > start_sec, "invariant" ); + + double conc_overhead[MaxGCOverheadGroupNum]; + COTracker::totalConcOverhead(end_sec, _group_num, conc_overhead); + add_conc_overhead(start_sec, end_sec, conc_overhead); + _prev_end_sec = end_sec; +} + +void +GCOverheadReporter::record_stw_start(double start_sec) { + guarantee( start_sec > _prev_end_sec, "invariant" ); + collect_and_record_conc_overhead(start_sec); +} + +void +GCOverheadReporter::record_stw_end(double end_sec) { + double start_sec = _prev_end_sec; + COTracker::updateAllForSTW(start_sec, end_sec); + add_stw_overhead(start_sec, end_sec, 1.0); + + _prev_end_sec = end_sec; +} + +void +GCOverheadReporter::print() const { + tty->print_cr(""); + tty->print_cr("GC Overhead (%d entries)", _curr - _base); + tty->print_cr(""); + GCOverheadReporterEntry* curr = _base; + while (curr < _curr) { + double total = curr->_stw_overhead; + for (size_t i = 0; i < _group_num; ++i) + total += curr->_conc_overhead[i]; + + tty->print("OVERHEAD %12.8lf %12.8lf ", + curr->_start_sec, curr->_end_sec); + + for (size_t i = 0; i < _group_num; ++i) + tty->print("%s %12.8lf ", _group_names[i], curr->_conc_overhead[i]); + + tty->print_cr("STW %12.8lf TOT %12.8lf", curr->_stw_overhead, total); + ++curr; + } + tty->print_cr(""); +} + +// statics + +void +GCOverheadReporter::initGCOverheadReporter(size_t group_num, + const char* group_names[]) { + guarantee( _reporter == NULL, "should only be called once" ); + guarantee( 0 <= group_num && group_num <= MaxGCOverheadGroupNum, + "precondition" ); + guarantee( group_names != NULL, "pre-condition" ); + + if (GCOverheadReporting) { + _reporter = new GCOverheadReporter(group_num, group_names); + new COReportingThread(_reporter); + } +} + +void +GCOverheadReporter::recordSTWStart(double start_sec) { + if (_reporter != NULL) + _reporter->record_stw_start(start_sec); +} + +void +GCOverheadReporter::recordSTWEnd(double end_sec) { + if (_reporter != NULL) + _reporter->record_stw_end(end_sec); +} + +void +GCOverheadReporter::printGCOverhead() { + if (_reporter != NULL) + _reporter->print(); +}