# HG changeset patch # User ysr # Date 1204324976 28800 # Node ID 6432c3bb624034d7b359b3d6d6a320c94b8bdd9b # Parent 3c1dbcaaab1d85cf9d3b26f8722adc4603bf2c10 6668743: CMS: Consolidate block statistics reporting code Summary: Reduce the amount of related code replication and improve pretty printing. Reviewed-by: jmasa diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp Tue Feb 26 15:57:49 2008 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp Fri Feb 29 14:42:56 2008 -0800 @@ -1071,85 +1071,56 @@ // for each list in the tree. Also print some summary // information. class printTreeCensusClosure : public AscendTreeCensusClosure { + int _print_line; size_t _totalFree; - AllocationStats _totals; - size_t _count; + FreeList _total; public: printTreeCensusClosure() { + _print_line = 0; _totalFree = 0; - _count = 0; - _totals.initialize(); } - AllocationStats* totals() { return &_totals; } - size_t count() { return _count; } - void increment_count_by(size_t v) { _count += v; } + FreeList* total() { return &_total; } size_t totalFree() { return _totalFree; } - void increment_totalFree_by(size_t v) { _totalFree += v; } void do_list(FreeList* fl) { - bool nl = false; // "maybe this is not needed" isNearLargestChunk(fl->head()); - - gclog_or_tty->print("%c %4d\t\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "\n", - " n"[nl], fl->size(), fl->bfrSurp(), fl->surplus(), - fl->desired(), fl->prevSweep(), fl->beforeSweep(), fl->count(), - fl->coalBirths(), fl->coalDeaths(), fl->splitBirths(), - fl->splitDeaths()); - - increment_totalFree_by(fl->count() * fl->size()); - increment_count_by(fl->count()); - totals()->set_bfrSurp(totals()->bfrSurp() + fl->bfrSurp()); - totals()->set_surplus(totals()->splitDeaths() + fl->surplus()); - totals()->set_prevSweep(totals()->prevSweep() + fl->prevSweep()); - totals()->set_beforeSweep(totals()->beforeSweep() + fl->beforeSweep()); - totals()->set_coalBirths(totals()->coalBirths() + fl->coalBirths()); - totals()->set_coalDeaths(totals()->coalDeaths() + fl->coalDeaths()); - totals()->set_splitBirths(totals()->splitBirths() + fl->splitBirths()); - totals()->set_splitDeaths(totals()->splitDeaths() + fl->splitDeaths()); + if (++_print_line >= 40) { + FreeList::print_labels_on(gclog_or_tty, "size"); + _print_line = 0; + } + fl->print_on(gclog_or_tty); + _totalFree += fl->count() * fl->size() ; + total()->set_count( total()->count() + fl->count() ); + total()->set_bfrSurp( total()->bfrSurp() + fl->bfrSurp() ); + total()->set_surplus( total()->splitDeaths() + fl->surplus() ); + total()->set_desired( total()->desired() + fl->desired() ); + total()->set_prevSweep( total()->prevSweep() + fl->prevSweep() ); + total()->set_beforeSweep(total()->beforeSweep() + fl->beforeSweep()); + total()->set_coalBirths( total()->coalBirths() + fl->coalBirths() ); + total()->set_coalDeaths( total()->coalDeaths() + fl->coalDeaths() ); + total()->set_splitBirths(total()->splitBirths() + fl->splitBirths()); + total()->set_splitDeaths(total()->splitDeaths() + fl->splitDeaths()); } }; void BinaryTreeDictionary::printDictCensus(void) const { gclog_or_tty->print("\nBinaryTree\n"); - gclog_or_tty->print( - "%4s\t\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" - "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "\n", - "size", "bfrsurp", "surplus", "desired", "prvSwep", "bfrSwep", - "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); - + FreeList::print_labels_on(gclog_or_tty, "size"); printTreeCensusClosure ptc; ptc.do_tree(root()); - gclog_or_tty->print( - "\t\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" - "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "\n", - "bfrsurp", "surplus", "prvSwep", "bfrSwep", - "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); + FreeList* total = ptc.total(); + FreeList::print_labels_on(gclog_or_tty, " "); + total->print_on(gclog_or_tty, "TOTAL\t"); gclog_or_tty->print( - "%s\t\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" "\n", - "totl", - ptc.totals()->bfrSurp(), - ptc.totals()->surplus(), - ptc.totals()->prevSweep(), - ptc.totals()->beforeSweep(), - ptc.count(), - ptc.totals()->coalBirths(), - ptc.totals()->coalDeaths(), - ptc.totals()->splitBirths(), - ptc.totals()->splitDeaths()); - gclog_or_tty->print("totalFree(words): %7d growth: %8.5f deficit: %8.5f\n", + "totalFree(words): " SIZE_FORMAT_W(16) + " growth: %8.5f deficit: %8.5f\n", ptc.totalFree(), - (double)(ptc.totals()->splitBirths()+ptc.totals()->coalBirths() - -ptc.totals()->splitDeaths()-ptc.totals()->coalDeaths()) - /(ptc.totals()->prevSweep() != 0 ? - (double)ptc.totals()->prevSweep() : 1.0), - (double)(ptc.totals()->desired() - ptc.count()) - /(ptc.totals()->desired() != 0 ? - (double)ptc.totals()->desired() : 1.0)); + (double)(total->splitBirths() + total->coalBirths() + - total->splitDeaths() - total->coalDeaths()) + /(total->prevSweep() != 0 ? (double)total->prevSweep() : 1.0), + (double)(total->desired() - total->count()) + /(total->desired() != 0 ? (double)total->desired() : 1.0)); } // Verify the following tree invariants: diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Feb 26 15:57:49 2008 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Feb 29 14:42:56 2008 -0800 @@ -1835,7 +1835,7 @@ guarantee(false, "NYI"); } -bool CompactibleFreeListSpace::linearAllocationWouldFail() { +bool CompactibleFreeListSpace::linearAllocationWouldFail() const { return _smallLinearAllocBlock._word_size == 0; } @@ -1906,6 +1906,13 @@ } } +// Support for concurrent collection policy decisions. +bool CompactibleFreeListSpace::should_concurrent_collect() const { + // In the future we might want to add in frgamentation stats -- + // including erosion of the "mountain" into this decision as well. + return !adaptive_freelists() && linearAllocationWouldFail(); +} + // Support for compaction void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) { @@ -2013,11 +2020,11 @@ } } -void CompactibleFreeListSpace::endSweepFLCensus(int sweepCt) { +void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { setFLSurplus(); setFLHints(); if (PrintGC && PrintFLSCensus > 0) { - printFLCensus(sweepCt); + printFLCensus(sweep_count); } clearFLCensus(); assert_locked(); @@ -2293,59 +2300,37 @@ } #endif -void CompactibleFreeListSpace::printFLCensus(int sweepCt) const { +void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { assert_lock_strong(&_freelistLock); - ssize_t bfrSurp = 0; - ssize_t surplus = 0; - ssize_t desired = 0; - ssize_t prevSweep = 0; - ssize_t beforeSweep = 0; - ssize_t count = 0; - ssize_t coalBirths = 0; - ssize_t coalDeaths = 0; - ssize_t splitBirths = 0; - ssize_t splitDeaths = 0; - gclog_or_tty->print("end sweep# %d\n", sweepCt); - gclog_or_tty->print("%4s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" - "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" - "%7s\t" "\n", - "size", "bfrsurp", "surplus", "desired", "prvSwep", - "bfrSwep", "count", "cBirths", "cDeaths", "sBirths", - "sDeaths"); - + FreeList total; + gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); + FreeList::print_labels_on(gclog_or_tty, "size"); size_t totalFree = 0; for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { const FreeList *fl = &_indexedFreeList[i]; - totalFree += fl->count() * fl->size(); - - gclog_or_tty->print("%4d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "\n", - fl->size(), fl->bfrSurp(), fl->surplus(), fl->desired(), - fl->prevSweep(), fl->beforeSweep(), fl->count(), fl->coalBirths(), - fl->coalDeaths(), fl->splitBirths(), fl->splitDeaths()); - bfrSurp += fl->bfrSurp(); - surplus += fl->surplus(); - desired += fl->desired(); - prevSweep += fl->prevSweep(); - beforeSweep += fl->beforeSweep(); - count += fl->count(); - coalBirths += fl->coalBirths(); - coalDeaths += fl->coalDeaths(); - splitBirths += fl->splitBirths(); - splitDeaths += fl->splitDeaths(); + totalFree += fl->count() * fl->size(); + if (i % (40*IndexSetStride) == 0) { + FreeList::print_labels_on(gclog_or_tty, "size"); + } + fl->print_on(gclog_or_tty); + total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() ); + total.set_surplus( total.surplus() + fl->surplus() ); + total.set_desired( total.desired() + fl->desired() ); + total.set_prevSweep( total.prevSweep() + fl->prevSweep() ); + total.set_beforeSweep(total.beforeSweep() + fl->beforeSweep()); + total.set_count( total.count() + fl->count() ); + total.set_coalBirths( total.coalBirths() + fl->coalBirths() ); + total.set_coalDeaths( total.coalDeaths() + fl->coalDeaths() ); + total.set_splitBirths(total.splitBirths() + fl->splitBirths()); + total.set_splitDeaths(total.splitDeaths() + fl->splitDeaths()); } - gclog_or_tty->print("%4s\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" - "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" "\n", - "totl", - bfrSurp, surplus, desired, prevSweep, beforeSweep, - count, coalBirths, coalDeaths, splitBirths, splitDeaths); - gclog_or_tty->print_cr("Total free in indexed lists %d words", totalFree); + total.print_on(gclog_or_tty, "TOTAL"); + gclog_or_tty->print_cr("Total free in indexed lists " + SIZE_FORMAT " words", totalFree); gclog_or_tty->print("growth: %8.5f deficit: %8.5f\n", - (double)(splitBirths+coalBirths-splitDeaths-coalDeaths)/ - (prevSweep != 0 ? (double)prevSweep : 1.0), - (double)(desired - count)/(desired != 0 ? (double)desired : 1.0)); + (double)(total.splitBirths()+total.coalBirths()-total.splitDeaths()-total.coalDeaths())/ + (total.prevSweep() != 0 ? (double)total.prevSweep() : 1.0), + (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0)); _dictionary->printDictCensus(); } diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Feb 26 15:57:49 2008 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Fri Feb 29 14:42:56 2008 -0800 @@ -418,7 +418,7 @@ // chunk exists, return NULL. FreeChunk* find_chunk_at_end(); - bool adaptive_freelists() { return _adaptive_freelists; } + bool adaptive_freelists() const { return _adaptive_freelists; } void set_collector(CMSCollector* collector) { _collector = collector; } @@ -566,7 +566,7 @@ FreeChunk* allocateScratch(size_t size); // returns true if either the small or large linear allocation buffer is empty. - bool linearAllocationWouldFail(); + bool linearAllocationWouldFail() const; // Adjust the chunk for the minimum size. This version is called in // most cases in CompactibleFreeListSpace methods. @@ -585,6 +585,9 @@ void addChunkAndRepairOffsetTable(HeapWord* chunk, size_t size, bool coalesced); + // Support for decisions regarding concurrent collection policy + bool should_concurrent_collect() const; + // Support for compaction void prepare_for_compaction(CompactPoint* cp); void adjust_pointers(); @@ -622,7 +625,7 @@ // coalescing of chunks during the sweep of garbage. // Print the statistics for the free lists. - void printFLCensus(int sweepCt) const; + void printFLCensus(size_t sweep_count) const; // Statistics functions // Initialize census for lists before the sweep. @@ -635,12 +638,11 @@ // Clear the census for each of the free lists. void clearFLCensus(); // Perform functions for the census after the end of the sweep. - void endSweepFLCensus(int sweepCt); + void endSweepFLCensus(size_t sweep_count); // Return true if the count of free chunks is greater // than the desired number of free chunks. bool coalOverPopulated(size_t size); - // Record (for each size): // // split-births = #chunks added due to splits in (prev-sweep-end, diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp Tue Feb 26 15:57:49 2008 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp Fri Feb 29 14:42:56 2008 -0800 @@ -302,3 +302,29 @@ #endif } #endif + +// Print the "label line" for free list stats. +void FreeList::print_labels_on(outputStream* st, const char* c) { + st->print("%16s\t", c); + st->print("%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" + "%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" "\n", + "bfrsurp", "surplus", "desired", "prvSwep", "bfrSwep", + "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); +} + +// Print the AllocationStats for the given free list. If the second argument +// to the call is a non-null string, it is printed in the first column; +// otherwise, if the argument is null (the default), then the size of the +// (free list) block is printed in the first column. +void FreeList::print_on(outputStream* st, const char* c) const { + if (c != NULL) { + st->print("%16s", c); + } else { + st->print(SIZE_FORMAT_W(16), size()); + } + st->print("\t" + SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" + SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\n", + bfrSurp(), surplus(), desired(), prevSweep(), beforeSweep(), + count(), coalBirths(), coalDeaths(), splitBirths(), splitDeaths()); +} diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp Tue Feb 26 15:57:49 2008 -0800 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp Fri Feb 29 14:42:56 2008 -0800 @@ -38,6 +38,7 @@ class FreeList VALUE_OBJ_CLASS_SPEC { friend class CompactibleFreeListSpace; + friend class printTreeCensusClosure; FreeChunk* _head; // List of free chunks FreeChunk* _tail; // Tail of list of free chunks size_t _size; // Size in Heap words of each chunks @@ -63,10 +64,11 @@ protected: void init_statistics(); void set_count(ssize_t v) { _count = v;} - void increment_count() { _count++; } + void increment_count() { _count++; } void decrement_count() { _count--; - assert(_count >= 0, "Count should not be negative"); } + assert(_count >= 0, "Count should not be negative"); + } public: // Constructor @@ -159,6 +161,10 @@ ssize_t desired() const { return _allocation_stats.desired(); } + void set_desired(ssize_t v) { + assert_proper_lock_protection(); + _allocation_stats.set_desired(v); + } void compute_desired(float inter_sweep_current, float inter_sweep_estimate) { assert_proper_lock_protection(); @@ -298,4 +304,8 @@ // Verify that the chunk is in the list. // found. Return NULL if "fc" is not found. bool verifyChunkInFreeLists(FreeChunk* fc) const; + + // Printing support + static void print_labels_on(outputStream* st, const char* c); + void print_on(outputStream* st, const char* c = NULL) const; }; diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/gc_implementation/includeDB_gc_shared --- a/src/share/vm/gc_implementation/includeDB_gc_shared Tue Feb 26 15:57:49 2008 -0800 +++ b/src/share/vm/gc_implementation/includeDB_gc_shared Fri Feb 29 14:42:56 2008 -0800 @@ -19,15 +19,22 @@ // 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. -// +// // // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! -gcAdaptivePolicyCounters.hpp adaptiveSizePolicy.hpp -gcAdaptivePolicyCounters.hpp gcPolicyCounters.hpp +allocationStats.cpp allocationStats.hpp +allocationStats.cpp ostream.hpp -gcAdaptivePolicyCounters.cpp resourceArea.hpp +allocationStats.hpp allocation.hpp +allocationStats.hpp gcUtil.hpp +allocationStats.hpp globalDefinitions.hpp + +gcAdaptivePolicyCounters.hpp adaptiveSizePolicy.hpp +gcAdaptivePolicyCounters.hpp gcPolicyCounters.hpp + +gcAdaptivePolicyCounters.cpp resourceArea.hpp gcAdaptivePolicyCounters.cpp gcAdaptivePolicyCounters.hpp gSpaceCounters.cpp generation.hpp @@ -44,7 +51,7 @@ isGCActiveMark.hpp parallelScavengeHeap.hpp -markSweep.inline.hpp psParallelCompact.hpp +markSweep.inline.hpp psParallelCompact.hpp mutableNUMASpace.cpp mutableNUMASpace.hpp mutableNUMASpace.cpp sharedHeap.hpp diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/gc_implementation/shared/allocationStats.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/gc_implementation/shared/allocationStats.cpp Fri Feb 29 14:42:56 2008 -0800 @@ -0,0 +1,30 @@ +/* + * Copyright 2005 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/_allocationStats.cpp.incl" + +// Technically this should be derived from machine speed, and +// ideally it would be dynamically adjusted. +float AllocationStats::_threshold = ((float)CMS_SweepTimerThresholdMillis)/1000; diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/gc_implementation/shared/allocationStats.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/gc_implementation/shared/allocationStats.hpp Fri Feb 29 14:42:56 2008 -0800 @@ -0,0 +1,138 @@ +/* + * Copyright 2001-2005 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. + * + */ + +class AllocationStats VALUE_OBJ_CLASS_SPEC { + // A duration threshold (in ms) used to filter + // possibly unreliable samples. + static float _threshold; + + // We measure the demand between the end of the previous sweep and + // beginning of this sweep: + // Count(end_last_sweep) - Count(start_this_sweep) + // + splitBirths(between) - splitDeaths(between) + // The above number divided by the time since the start [END???] of the + // previous sweep gives us a time rate of demand for blocks + // of this size. We compute a padded average of this rate as + // our current estimate for the time rate of demand for blocks + // of this size. Similarly, we keep a padded average for the time + // between sweeps. Our current estimate for demand for blocks of + // this size is then simply computed as the product of these two + // estimates. + AdaptivePaddedAverage _demand_rate_estimate; + + ssize_t _desired; // Estimate computed as described above + ssize_t _coalDesired; // desired +/- small-percent for tuning coalescing + + ssize_t _surplus; // count - (desired +/- small-percent), + // used to tune splitting in best fit + ssize_t _bfrSurp; // surplus at start of current sweep + ssize_t _prevSweep; // count from end of previous sweep + ssize_t _beforeSweep; // count from before current sweep + ssize_t _coalBirths; // additional chunks from coalescing + ssize_t _coalDeaths; // loss from coalescing + ssize_t _splitBirths; // additional chunks from splitting + ssize_t _splitDeaths; // loss from splitting + size_t _returnedBytes; // number of bytes returned to list. + public: + void initialize() { + AdaptivePaddedAverage* dummy = + new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight, + CMS_FLSPadding); + _desired = 0; + _coalDesired = 0; + _surplus = 0; + _bfrSurp = 0; + _prevSweep = 0; + _beforeSweep = 0; + _coalBirths = 0; + _coalDeaths = 0; + _splitBirths = 0; + _splitDeaths = 0; + _returnedBytes = 0; + } + + AllocationStats() { + initialize(); + } + // The rate estimate is in blocks per second. + void compute_desired(size_t count, + float inter_sweep_current, + float inter_sweep_estimate) { + // If the latest inter-sweep time is below our granularity + // of measurement, we may call in here with + // inter_sweep_current == 0. However, even for suitably small + // but non-zero inter-sweep durations, we may not trust the accuracy + // of accumulated data, since it has not been "integrated" + // (read "low-pass-filtered") long enough, and would be + // vulnerable to noisy glitches. In such cases, we + // ignore the current sample and use currently available + // historical estimates. + if (inter_sweep_current > _threshold) { + ssize_t demand = prevSweep() - count + splitBirths() - splitDeaths(); + float rate = ((float)demand)/inter_sweep_current; + _demand_rate_estimate.sample(rate); + _desired = (ssize_t)(_demand_rate_estimate.padded_average() + *inter_sweep_estimate); + } + } + + ssize_t desired() const { return _desired; } + void set_desired(ssize_t v) { _desired = v; } + + ssize_t coalDesired() const { return _coalDesired; } + void set_coalDesired(ssize_t v) { _coalDesired = v; } + + ssize_t surplus() const { return _surplus; } + void set_surplus(ssize_t v) { _surplus = v; } + void increment_surplus() { _surplus++; } + void decrement_surplus() { _surplus--; } + + ssize_t bfrSurp() const { return _bfrSurp; } + void set_bfrSurp(ssize_t v) { _bfrSurp = v; } + ssize_t prevSweep() const { return _prevSweep; } + void set_prevSweep(ssize_t v) { _prevSweep = v; } + ssize_t beforeSweep() const { return _beforeSweep; } + void set_beforeSweep(ssize_t v) { _beforeSweep = v; } + + ssize_t coalBirths() const { return _coalBirths; } + void set_coalBirths(ssize_t v) { _coalBirths = v; } + void increment_coalBirths() { _coalBirths++; } + + ssize_t coalDeaths() const { return _coalDeaths; } + void set_coalDeaths(ssize_t v) { _coalDeaths = v; } + void increment_coalDeaths() { _coalDeaths++; } + + ssize_t splitBirths() const { return _splitBirths; } + void set_splitBirths(ssize_t v) { _splitBirths = v; } + void increment_splitBirths() { _splitBirths++; } + + ssize_t splitDeaths() const { return _splitDeaths; } + void set_splitDeaths(ssize_t v) { _splitDeaths = v; } + void increment_splitDeaths() { _splitDeaths++; } + + NOT_PRODUCT( + size_t returnedBytes() const { return _returnedBytes; } + void set_returnedBytes(size_t v) { _returnedBytes = v; } + ) +}; diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/includeDB_core --- a/src/share/vm/includeDB_core Tue Feb 26 15:57:49 2008 -0800 +++ b/src/share/vm/includeDB_core Fri Feb 29 14:42:56 2008 -0800 @@ -19,7 +19,7 @@ // 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. -// +// // // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! @@ -46,13 +46,13 @@ // as dependencies. Header files named H.inline.hpp generally contain // bodies for inline functions declared in H.hpp. // -// NOTE: Files that use the token "generate_platform_dependent_include" +// NOTE: Files that use the token "generate_platform_dependent_include" // are expected to contain macro references like , , ... and // makedeps has a dependency on these platform files looking like: -// foo_.trailing_string +// foo_.trailing_string // (where "trailing_string" can be any legal filename strings but typically // is "hpp" or "inline.hpp"). -// +// // The dependency in makedeps (and enforced) is that an underscore // will precedure the macro invocation. Note that this restriction // is only enforced on filenames that have the dependency token @@ -148,12 +148,6 @@ allocation.inline.hpp os.hpp -allocationStats.cpp allocationStats.hpp - -allocationStats.hpp allocation.hpp -allocationStats.hpp gcUtil.hpp -allocationStats.hpp globalDefinitions.hpp - aprofiler.cpp aprofiler.hpp aprofiler.cpp collectedHeap.inline.hpp aprofiler.cpp oop.inline.hpp @@ -1935,7 +1929,7 @@ init.cpp bytecodes.hpp init.cpp collectedHeap.hpp -init.cpp handles.inline.hpp +init.cpp handles.inline.hpp init.cpp icBuffer.hpp init.cpp icache.hpp init.cpp init.hpp diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/memory/allocationStats.cpp --- a/src/share/vm/memory/allocationStats.cpp Tue Feb 26 15:57:49 2008 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright 2005 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/_allocationStats.cpp.incl" - -// Technically this should be derived from machine speed, and -// ideally it would be dynamically adjusted. -float AllocationStats::_threshold = ((float)CMS_SweepTimerThresholdMillis)/1000; diff -r 3c1dbcaaab1d -r 6432c3bb6240 src/share/vm/memory/allocationStats.hpp --- a/src/share/vm/memory/allocationStats.hpp Tue Feb 26 15:57:49 2008 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -/* - * Copyright 2001-2005 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. - * - */ - -class AllocationStats VALUE_OBJ_CLASS_SPEC { - // A duration threshold (in ms) used to filter - // possibly unreliable samples. - static float _threshold; - - // We measure the demand between the end of the previous sweep and - // beginning of this sweep: - // Count(end_last_sweep) - Count(start_this_sweep) - // + splitBirths(between) - splitDeaths(between) - // The above number divided by the time since the start [END???] of the - // previous sweep gives us a time rate of demand for blocks - // of this size. We compute a padded average of this rate as - // our current estimate for the time rate of demand for blocks - // of this size. Similarly, we keep a padded average for the time - // between sweeps. Our current estimate for demand for blocks of - // this size is then simply computed as the product of these two - // estimates. - AdaptivePaddedAverage _demand_rate_estimate; - - ssize_t _desired; // Estimate computed as described above - ssize_t _coalDesired; // desired +/- small-percent for tuning coalescing - - ssize_t _surplus; // count - (desired +/- small-percent), - // used to tune splitting in best fit - ssize_t _bfrSurp; // surplus at start of current sweep - ssize_t _prevSweep; // count from end of previous sweep - ssize_t _beforeSweep; // count from before current sweep - ssize_t _coalBirths; // additional chunks from coalescing - ssize_t _coalDeaths; // loss from coalescing - ssize_t _splitBirths; // additional chunks from splitting - ssize_t _splitDeaths; // loss from splitting - size_t _returnedBytes; // number of bytes returned to list. - public: - void initialize() { - AdaptivePaddedAverage* dummy = - new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight, - CMS_FLSPadding); - _desired = 0; - _coalDesired = 0; - _surplus = 0; - _bfrSurp = 0; - _prevSweep = 0; - _beforeSweep = 0; - _coalBirths = 0; - _coalDeaths = 0; - _splitBirths = 0; - _splitDeaths = 0; - _returnedBytes = 0; - } - - AllocationStats() { - initialize(); - } - // The rate estimate is in blocks per second. - void compute_desired(size_t count, - float inter_sweep_current, - float inter_sweep_estimate) { - // If the latest inter-sweep time is below our granularity - // of measurement, we may call in here with - // inter_sweep_current == 0. However, even for suitably small - // but non-zero inter-sweep durations, we may not trust the accuracy - // of accumulated data, since it has not been "integrated" - // (read "low-pass-filtered") long enough, and would be - // vulnerable to noisy glitches. In such cases, we - // ignore the current sample and use currently available - // historical estimates. - if (inter_sweep_current > _threshold) { - ssize_t demand = prevSweep() - count + splitBirths() - splitDeaths(); - float rate = ((float)demand)/inter_sweep_current; - _demand_rate_estimate.sample(rate); - _desired = (ssize_t)(_demand_rate_estimate.padded_average() - *inter_sweep_estimate); - } - } - - ssize_t desired() const { return _desired; } - ssize_t coalDesired() const { return _coalDesired; } - void set_coalDesired(ssize_t v) { _coalDesired = v; } - - ssize_t surplus() const { return _surplus; } - void set_surplus(ssize_t v) { _surplus = v; } - void increment_surplus() { _surplus++; } - void decrement_surplus() { _surplus--; } - - ssize_t bfrSurp() const { return _bfrSurp; } - void set_bfrSurp(ssize_t v) { _bfrSurp = v; } - ssize_t prevSweep() const { return _prevSweep; } - void set_prevSweep(ssize_t v) { _prevSweep = v; } - ssize_t beforeSweep() const { return _beforeSweep; } - void set_beforeSweep(ssize_t v) { _beforeSweep = v; } - - ssize_t coalBirths() const { return _coalBirths; } - void set_coalBirths(ssize_t v) { _coalBirths = v; } - void increment_coalBirths() { _coalBirths++; } - - ssize_t coalDeaths() const { return _coalDeaths; } - void set_coalDeaths(ssize_t v) { _coalDeaths = v; } - void increment_coalDeaths() { _coalDeaths++; } - - ssize_t splitBirths() const { return _splitBirths; } - void set_splitBirths(ssize_t v) { _splitBirths = v; } - void increment_splitBirths() { _splitBirths++; } - - ssize_t splitDeaths() const { return _splitDeaths; } - void set_splitDeaths(ssize_t v) { _splitDeaths = v; } - void increment_splitDeaths() { _splitDeaths++; } - - NOT_PRODUCT( - size_t returnedBytes() const { return _returnedBytes; } - void set_returnedBytes(size_t v) { _returnedBytes = v; } - ) -};