提交 6538251a 编写于 作者: Y ysr

6668743: CMS: Consolidate block statistics reporting code

Summary: Reduce the amount of related code replication and improve pretty printing.
Reviewed-by: jmasa
上级 f110fc31
......@@ -1071,85 +1071,56 @@ void BinaryTreeDictionary::reportStatistics() const {
// 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());
FreeList* total = ptc.total();
FreeList::print_labels_on(gclog_or_tty, " ");
total->print_on(gclog_or_tty, "TOTAL\t");
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");
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:
......
......@@ -1835,7 +1835,7 @@ void CompactibleFreeListSpace::object_iterate_since_last_GC(ObjectClosure* cl) {
guarantee(false, "NYI");
}
bool CompactibleFreeListSpace::linearAllocationWouldFail() {
bool CompactibleFreeListSpace::linearAllocationWouldFail() const {
return _smallLinearAllocBlock._word_size == 0;
}
......@@ -1906,6 +1906,13 @@ CompactibleFreeListSpace::refillLinearAllocBlock(LinearAllocBlock* blk) {
}
}
// 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::clearFLCensus() {
}
}
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 @@ void CompactibleFreeListSpace::checkFreeListConsistency() const {
}
#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();
}
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);
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());
}
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();
}
......
......@@ -418,7 +418,7 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// 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 @@ class CompactibleFreeListSpace: public CompactibleSpace {
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 @@ class CompactibleFreeListSpace: public CompactibleSpace {
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 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// 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 @@ class CompactibleFreeListSpace: public CompactibleSpace {
// 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,
......
......@@ -302,3 +302,29 @@ void FreeList::assert_proper_lock_protection_work() const {
#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());
}
......@@ -38,6 +38,7 @@ class Mutex;
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 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
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 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
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 @@ class FreeList VALUE_OBJ_CLASS_SPEC {
// 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;
};
......@@ -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
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 resourceArea.hpp
gcAdaptivePolicyCounters.cpp gcAdaptivePolicyCounters.hpp
gSpaceCounters.cpp generation.hpp
......@@ -44,7 +51,7 @@ immutableSpace.cpp universe.hpp
isGCActiveMark.hpp parallelScavengeHeap.hpp
markSweep.inline.hpp psParallelCompact.hpp
markSweep.inline.hpp psParallelCompact.hpp
mutableNUMASpace.cpp mutableNUMASpace.hpp
mutableNUMASpace.cpp sharedHeap.hpp
......
......@@ -98,6 +98,8 @@ class AllocationStats VALUE_OBJ_CLASS_SPEC {
}
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; }
......
......@@ -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.hpp globals.hpp
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 @@ icache_<arch>.hpp generate_platform_dependent_include
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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册