6668743: CMS: Consolidate block statistics reporting code
Summary: Reduce the amount of related code replication and improve pretty printing.
Reviewed-by: jmasa
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp Tue Feb 26 15:57:49 2008 -0800
+++ b/hotspot/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:
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Feb 26 15:57:49 2008 -0800
+++ b/hotspot/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();
}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Feb 26 15:57:49 2008 -0800
+++ b/hotspot/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,
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp Tue Feb 26 15:57:49 2008 -0800
+++ b/hotspot/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());
+}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp Tue Feb 26 15:57:49 2008 -0800
+++ b/hotspot/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;
};
--- a/hotspot/src/share/vm/gc_implementation/includeDB_gc_shared Tue Feb 26 15:57:49 2008 -0800
+++ b/hotspot/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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/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;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/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; }
+ )
+};
--- a/hotspot/src/share/vm/includeDB_core Tue Feb 26 15:57:49 2008 -0800
+++ b/hotspot/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 <os>, <arch_model>, ... and
// makedeps has a dependency on these platform files looking like:
-// foo_<macro>.trailing_string
+// foo_<macro>.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
--- a/hotspot/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;
--- a/hotspot/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; }
- )
-};