Fri, 29 Feb 2008 14:42:56 -0800
6668743: CMS: Consolidate block statistics reporting code
Summary: Reduce the amount of related code replication and improve pretty printing.
Reviewed-by: jmasa
1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp Tue Feb 26 15:57:49 2008 -0800 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp Fri Feb 29 14:42:56 2008 -0800 1.3 @@ -1071,85 +1071,56 @@ 1.4 // for each list in the tree. Also print some summary 1.5 // information. 1.6 class printTreeCensusClosure : public AscendTreeCensusClosure { 1.7 + int _print_line; 1.8 size_t _totalFree; 1.9 - AllocationStats _totals; 1.10 - size_t _count; 1.11 + FreeList _total; 1.12 1.13 public: 1.14 printTreeCensusClosure() { 1.15 + _print_line = 0; 1.16 _totalFree = 0; 1.17 - _count = 0; 1.18 - _totals.initialize(); 1.19 } 1.20 - AllocationStats* totals() { return &_totals; } 1.21 - size_t count() { return _count; } 1.22 - void increment_count_by(size_t v) { _count += v; } 1.23 + FreeList* total() { return &_total; } 1.24 size_t totalFree() { return _totalFree; } 1.25 - void increment_totalFree_by(size_t v) { _totalFree += v; } 1.26 void do_list(FreeList* fl) { 1.27 - bool nl = false; // "maybe this is not needed" isNearLargestChunk(fl->head()); 1.28 - 1.29 - gclog_or_tty->print("%c %4d\t\t" "%7d\t" "%7d\t" 1.30 - "%7d\t" "%7d\t" "%7d\t" "%7d\t" 1.31 - "%7d\t" "%7d\t" "%7d\t" 1.32 - "%7d\t" "\n", 1.33 - " n"[nl], fl->size(), fl->bfrSurp(), fl->surplus(), 1.34 - fl->desired(), fl->prevSweep(), fl->beforeSweep(), fl->count(), 1.35 - fl->coalBirths(), fl->coalDeaths(), fl->splitBirths(), 1.36 - fl->splitDeaths()); 1.37 - 1.38 - increment_totalFree_by(fl->count() * fl->size()); 1.39 - increment_count_by(fl->count()); 1.40 - totals()->set_bfrSurp(totals()->bfrSurp() + fl->bfrSurp()); 1.41 - totals()->set_surplus(totals()->splitDeaths() + fl->surplus()); 1.42 - totals()->set_prevSweep(totals()->prevSweep() + fl->prevSweep()); 1.43 - totals()->set_beforeSweep(totals()->beforeSweep() + fl->beforeSweep()); 1.44 - totals()->set_coalBirths(totals()->coalBirths() + fl->coalBirths()); 1.45 - totals()->set_coalDeaths(totals()->coalDeaths() + fl->coalDeaths()); 1.46 - totals()->set_splitBirths(totals()->splitBirths() + fl->splitBirths()); 1.47 - totals()->set_splitDeaths(totals()->splitDeaths() + fl->splitDeaths()); 1.48 + if (++_print_line >= 40) { 1.49 + FreeList::print_labels_on(gclog_or_tty, "size"); 1.50 + _print_line = 0; 1.51 + } 1.52 + fl->print_on(gclog_or_tty); 1.53 + _totalFree += fl->count() * fl->size() ; 1.54 + total()->set_count( total()->count() + fl->count() ); 1.55 + total()->set_bfrSurp( total()->bfrSurp() + fl->bfrSurp() ); 1.56 + total()->set_surplus( total()->splitDeaths() + fl->surplus() ); 1.57 + total()->set_desired( total()->desired() + fl->desired() ); 1.58 + total()->set_prevSweep( total()->prevSweep() + fl->prevSweep() ); 1.59 + total()->set_beforeSweep(total()->beforeSweep() + fl->beforeSweep()); 1.60 + total()->set_coalBirths( total()->coalBirths() + fl->coalBirths() ); 1.61 + total()->set_coalDeaths( total()->coalDeaths() + fl->coalDeaths() ); 1.62 + total()->set_splitBirths(total()->splitBirths() + fl->splitBirths()); 1.63 + total()->set_splitDeaths(total()->splitDeaths() + fl->splitDeaths()); 1.64 } 1.65 }; 1.66 1.67 void BinaryTreeDictionary::printDictCensus(void) const { 1.68 1.69 gclog_or_tty->print("\nBinaryTree\n"); 1.70 - gclog_or_tty->print( 1.71 - "%4s\t\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" 1.72 - "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "\n", 1.73 - "size", "bfrsurp", "surplus", "desired", "prvSwep", "bfrSwep", 1.74 - "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); 1.75 - 1.76 + FreeList::print_labels_on(gclog_or_tty, "size"); 1.77 printTreeCensusClosure ptc; 1.78 ptc.do_tree(root()); 1.79 1.80 + FreeList* total = ptc.total(); 1.81 + FreeList::print_labels_on(gclog_or_tty, " "); 1.82 + total->print_on(gclog_or_tty, "TOTAL\t"); 1.83 gclog_or_tty->print( 1.84 - "\t\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" 1.85 - "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "\n", 1.86 - "bfrsurp", "surplus", "prvSwep", "bfrSwep", 1.87 - "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); 1.88 - gclog_or_tty->print( 1.89 - "%s\t\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" 1.90 - "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" "\n", 1.91 - "totl", 1.92 - ptc.totals()->bfrSurp(), 1.93 - ptc.totals()->surplus(), 1.94 - ptc.totals()->prevSweep(), 1.95 - ptc.totals()->beforeSweep(), 1.96 - ptc.count(), 1.97 - ptc.totals()->coalBirths(), 1.98 - ptc.totals()->coalDeaths(), 1.99 - ptc.totals()->splitBirths(), 1.100 - ptc.totals()->splitDeaths()); 1.101 - gclog_or_tty->print("totalFree(words): %7d growth: %8.5f deficit: %8.5f\n", 1.102 + "totalFree(words): " SIZE_FORMAT_W(16) 1.103 + " growth: %8.5f deficit: %8.5f\n", 1.104 ptc.totalFree(), 1.105 - (double)(ptc.totals()->splitBirths()+ptc.totals()->coalBirths() 1.106 - -ptc.totals()->splitDeaths()-ptc.totals()->coalDeaths()) 1.107 - /(ptc.totals()->prevSweep() != 0 ? 1.108 - (double)ptc.totals()->prevSweep() : 1.0), 1.109 - (double)(ptc.totals()->desired() - ptc.count()) 1.110 - /(ptc.totals()->desired() != 0 ? 1.111 - (double)ptc.totals()->desired() : 1.0)); 1.112 + (double)(total->splitBirths() + total->coalBirths() 1.113 + - total->splitDeaths() - total->coalDeaths()) 1.114 + /(total->prevSweep() != 0 ? (double)total->prevSweep() : 1.0), 1.115 + (double)(total->desired() - total->count()) 1.116 + /(total->desired() != 0 ? (double)total->desired() : 1.0)); 1.117 } 1.118 1.119 // Verify the following tree invariants:
2.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Feb 26 15:57:49 2008 -0800 2.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Feb 29 14:42:56 2008 -0800 2.3 @@ -1835,7 +1835,7 @@ 2.4 guarantee(false, "NYI"); 2.5 } 2.6 2.7 -bool CompactibleFreeListSpace::linearAllocationWouldFail() { 2.8 +bool CompactibleFreeListSpace::linearAllocationWouldFail() const { 2.9 return _smallLinearAllocBlock._word_size == 0; 2.10 } 2.11 2.12 @@ -1906,6 +1906,13 @@ 2.13 } 2.14 } 2.15 2.16 +// Support for concurrent collection policy decisions. 2.17 +bool CompactibleFreeListSpace::should_concurrent_collect() const { 2.18 + // In the future we might want to add in frgamentation stats -- 2.19 + // including erosion of the "mountain" into this decision as well. 2.20 + return !adaptive_freelists() && linearAllocationWouldFail(); 2.21 +} 2.22 + 2.23 // Support for compaction 2.24 2.25 void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) { 2.26 @@ -2013,11 +2020,11 @@ 2.27 } 2.28 } 2.29 2.30 -void CompactibleFreeListSpace::endSweepFLCensus(int sweepCt) { 2.31 +void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) { 2.32 setFLSurplus(); 2.33 setFLHints(); 2.34 if (PrintGC && PrintFLSCensus > 0) { 2.35 - printFLCensus(sweepCt); 2.36 + printFLCensus(sweep_count); 2.37 } 2.38 clearFLCensus(); 2.39 assert_locked(); 2.40 @@ -2293,59 +2300,37 @@ 2.41 } 2.42 #endif 2.43 2.44 -void CompactibleFreeListSpace::printFLCensus(int sweepCt) const { 2.45 +void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { 2.46 assert_lock_strong(&_freelistLock); 2.47 - ssize_t bfrSurp = 0; 2.48 - ssize_t surplus = 0; 2.49 - ssize_t desired = 0; 2.50 - ssize_t prevSweep = 0; 2.51 - ssize_t beforeSweep = 0; 2.52 - ssize_t count = 0; 2.53 - ssize_t coalBirths = 0; 2.54 - ssize_t coalDeaths = 0; 2.55 - ssize_t splitBirths = 0; 2.56 - ssize_t splitDeaths = 0; 2.57 - gclog_or_tty->print("end sweep# %d\n", sweepCt); 2.58 - gclog_or_tty->print("%4s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" 2.59 - "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" 2.60 - "%7s\t" "\n", 2.61 - "size", "bfrsurp", "surplus", "desired", "prvSwep", 2.62 - "bfrSwep", "count", "cBirths", "cDeaths", "sBirths", 2.63 - "sDeaths"); 2.64 - 2.65 + FreeList total; 2.66 + gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); 2.67 + FreeList::print_labels_on(gclog_or_tty, "size"); 2.68 size_t totalFree = 0; 2.69 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 2.70 const FreeList *fl = &_indexedFreeList[i]; 2.71 - totalFree += fl->count() * fl->size(); 2.72 - 2.73 - gclog_or_tty->print("%4d\t" "%7d\t" "%7d\t" "%7d\t" 2.74 - "%7d\t" "%7d\t" "%7d\t" "%7d\t" 2.75 - "%7d\t" "%7d\t" "%7d\t" "\n", 2.76 - fl->size(), fl->bfrSurp(), fl->surplus(), fl->desired(), 2.77 - fl->prevSweep(), fl->beforeSweep(), fl->count(), fl->coalBirths(), 2.78 - fl->coalDeaths(), fl->splitBirths(), fl->splitDeaths()); 2.79 - bfrSurp += fl->bfrSurp(); 2.80 - surplus += fl->surplus(); 2.81 - desired += fl->desired(); 2.82 - prevSweep += fl->prevSweep(); 2.83 - beforeSweep += fl->beforeSweep(); 2.84 - count += fl->count(); 2.85 - coalBirths += fl->coalBirths(); 2.86 - coalDeaths += fl->coalDeaths(); 2.87 - splitBirths += fl->splitBirths(); 2.88 - splitDeaths += fl->splitDeaths(); 2.89 + totalFree += fl->count() * fl->size(); 2.90 + if (i % (40*IndexSetStride) == 0) { 2.91 + FreeList::print_labels_on(gclog_or_tty, "size"); 2.92 + } 2.93 + fl->print_on(gclog_or_tty); 2.94 + total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() ); 2.95 + total.set_surplus( total.surplus() + fl->surplus() ); 2.96 + total.set_desired( total.desired() + fl->desired() ); 2.97 + total.set_prevSweep( total.prevSweep() + fl->prevSweep() ); 2.98 + total.set_beforeSweep(total.beforeSweep() + fl->beforeSweep()); 2.99 + total.set_count( total.count() + fl->count() ); 2.100 + total.set_coalBirths( total.coalBirths() + fl->coalBirths() ); 2.101 + total.set_coalDeaths( total.coalDeaths() + fl->coalDeaths() ); 2.102 + total.set_splitBirths(total.splitBirths() + fl->splitBirths()); 2.103 + total.set_splitDeaths(total.splitDeaths() + fl->splitDeaths()); 2.104 } 2.105 - gclog_or_tty->print("%4s\t" 2.106 - "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" 2.107 - "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" "\n", 2.108 - "totl", 2.109 - bfrSurp, surplus, desired, prevSweep, beforeSweep, 2.110 - count, coalBirths, coalDeaths, splitBirths, splitDeaths); 2.111 - gclog_or_tty->print_cr("Total free in indexed lists %d words", totalFree); 2.112 + total.print_on(gclog_or_tty, "TOTAL"); 2.113 + gclog_or_tty->print_cr("Total free in indexed lists " 2.114 + SIZE_FORMAT " words", totalFree); 2.115 gclog_or_tty->print("growth: %8.5f deficit: %8.5f\n", 2.116 - (double)(splitBirths+coalBirths-splitDeaths-coalDeaths)/ 2.117 - (prevSweep != 0 ? (double)prevSweep : 1.0), 2.118 - (double)(desired - count)/(desired != 0 ? (double)desired : 1.0)); 2.119 + (double)(total.splitBirths()+total.coalBirths()-total.splitDeaths()-total.coalDeaths())/ 2.120 + (total.prevSweep() != 0 ? (double)total.prevSweep() : 1.0), 2.121 + (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0)); 2.122 _dictionary->printDictCensus(); 2.123 } 2.124
3.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Feb 26 15:57:49 2008 -0800 3.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Fri Feb 29 14:42:56 2008 -0800 3.3 @@ -418,7 +418,7 @@ 3.4 // chunk exists, return NULL. 3.5 FreeChunk* find_chunk_at_end(); 3.6 3.7 - bool adaptive_freelists() { return _adaptive_freelists; } 3.8 + bool adaptive_freelists() const { return _adaptive_freelists; } 3.9 3.10 void set_collector(CMSCollector* collector) { _collector = collector; } 3.11 3.12 @@ -566,7 +566,7 @@ 3.13 FreeChunk* allocateScratch(size_t size); 3.14 3.15 // returns true if either the small or large linear allocation buffer is empty. 3.16 - bool linearAllocationWouldFail(); 3.17 + bool linearAllocationWouldFail() const; 3.18 3.19 // Adjust the chunk for the minimum size. This version is called in 3.20 // most cases in CompactibleFreeListSpace methods. 3.21 @@ -585,6 +585,9 @@ 3.22 void addChunkAndRepairOffsetTable(HeapWord* chunk, size_t size, 3.23 bool coalesced); 3.24 3.25 + // Support for decisions regarding concurrent collection policy 3.26 + bool should_concurrent_collect() const; 3.27 + 3.28 // Support for compaction 3.29 void prepare_for_compaction(CompactPoint* cp); 3.30 void adjust_pointers(); 3.31 @@ -622,7 +625,7 @@ 3.32 // coalescing of chunks during the sweep of garbage. 3.33 3.34 // Print the statistics for the free lists. 3.35 - void printFLCensus(int sweepCt) const; 3.36 + void printFLCensus(size_t sweep_count) const; 3.37 3.38 // Statistics functions 3.39 // Initialize census for lists before the sweep. 3.40 @@ -635,12 +638,11 @@ 3.41 // Clear the census for each of the free lists. 3.42 void clearFLCensus(); 3.43 // Perform functions for the census after the end of the sweep. 3.44 - void endSweepFLCensus(int sweepCt); 3.45 + void endSweepFLCensus(size_t sweep_count); 3.46 // Return true if the count of free chunks is greater 3.47 // than the desired number of free chunks. 3.48 bool coalOverPopulated(size_t size); 3.49 3.50 - 3.51 // Record (for each size): 3.52 // 3.53 // split-births = #chunks added due to splits in (prev-sweep-end,
4.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp Tue Feb 26 15:57:49 2008 -0800 4.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp Fri Feb 29 14:42:56 2008 -0800 4.3 @@ -302,3 +302,29 @@ 4.4 #endif 4.5 } 4.6 #endif 4.7 + 4.8 +// Print the "label line" for free list stats. 4.9 +void FreeList::print_labels_on(outputStream* st, const char* c) { 4.10 + st->print("%16s\t", c); 4.11 + st->print("%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" 4.12 + "%14s\t" "%14s\t" "%14s\t" "%14s\t" "%14s\t" "\n", 4.13 + "bfrsurp", "surplus", "desired", "prvSwep", "bfrSwep", 4.14 + "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); 4.15 +} 4.16 + 4.17 +// Print the AllocationStats for the given free list. If the second argument 4.18 +// to the call is a non-null string, it is printed in the first column; 4.19 +// otherwise, if the argument is null (the default), then the size of the 4.20 +// (free list) block is printed in the first column. 4.21 +void FreeList::print_on(outputStream* st, const char* c) const { 4.22 + if (c != NULL) { 4.23 + st->print("%16s", c); 4.24 + } else { 4.25 + st->print(SIZE_FORMAT_W(16), size()); 4.26 + } 4.27 + st->print("\t" 4.28 + 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" 4.29 + 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", 4.30 + bfrSurp(), surplus(), desired(), prevSweep(), beforeSweep(), 4.31 + count(), coalBirths(), coalDeaths(), splitBirths(), splitDeaths()); 4.32 +}
5.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp Tue Feb 26 15:57:49 2008 -0800 5.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp Fri Feb 29 14:42:56 2008 -0800 5.3 @@ -38,6 +38,7 @@ 5.4 5.5 class FreeList VALUE_OBJ_CLASS_SPEC { 5.6 friend class CompactibleFreeListSpace; 5.7 + friend class printTreeCensusClosure; 5.8 FreeChunk* _head; // List of free chunks 5.9 FreeChunk* _tail; // Tail of list of free chunks 5.10 size_t _size; // Size in Heap words of each chunks 5.11 @@ -63,10 +64,11 @@ 5.12 protected: 5.13 void init_statistics(); 5.14 void set_count(ssize_t v) { _count = v;} 5.15 - void increment_count() { _count++; } 5.16 + void increment_count() { _count++; } 5.17 void decrement_count() { 5.18 _count--; 5.19 - assert(_count >= 0, "Count should not be negative"); } 5.20 + assert(_count >= 0, "Count should not be negative"); 5.21 + } 5.22 5.23 public: 5.24 // Constructor 5.25 @@ -159,6 +161,10 @@ 5.26 ssize_t desired() const { 5.27 return _allocation_stats.desired(); 5.28 } 5.29 + void set_desired(ssize_t v) { 5.30 + assert_proper_lock_protection(); 5.31 + _allocation_stats.set_desired(v); 5.32 + } 5.33 void compute_desired(float inter_sweep_current, 5.34 float inter_sweep_estimate) { 5.35 assert_proper_lock_protection(); 5.36 @@ -298,4 +304,8 @@ 5.37 // Verify that the chunk is in the list. 5.38 // found. Return NULL if "fc" is not found. 5.39 bool verifyChunkInFreeLists(FreeChunk* fc) const; 5.40 + 5.41 + // Printing support 5.42 + static void print_labels_on(outputStream* st, const char* c); 5.43 + void print_on(outputStream* st, const char* c = NULL) const; 5.44 };
6.1 --- a/src/share/vm/gc_implementation/includeDB_gc_shared Tue Feb 26 15:57:49 2008 -0800 6.2 +++ b/src/share/vm/gc_implementation/includeDB_gc_shared Fri Feb 29 14:42:56 2008 -0800 6.3 @@ -19,15 +19,22 @@ 6.4 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 6.5 // CA 95054 USA or visit www.sun.com if you need additional information or 6.6 // have any questions. 6.7 -// 6.8 +// 6.9 // 6.10 6.11 // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! 6.12 6.13 -gcAdaptivePolicyCounters.hpp adaptiveSizePolicy.hpp 6.14 -gcAdaptivePolicyCounters.hpp gcPolicyCounters.hpp 6.15 +allocationStats.cpp allocationStats.hpp 6.16 +allocationStats.cpp ostream.hpp 6.17 6.18 -gcAdaptivePolicyCounters.cpp resourceArea.hpp 6.19 +allocationStats.hpp allocation.hpp 6.20 +allocationStats.hpp gcUtil.hpp 6.21 +allocationStats.hpp globalDefinitions.hpp 6.22 + 6.23 +gcAdaptivePolicyCounters.hpp adaptiveSizePolicy.hpp 6.24 +gcAdaptivePolicyCounters.hpp gcPolicyCounters.hpp 6.25 + 6.26 +gcAdaptivePolicyCounters.cpp resourceArea.hpp 6.27 gcAdaptivePolicyCounters.cpp gcAdaptivePolicyCounters.hpp 6.28 6.29 gSpaceCounters.cpp generation.hpp 6.30 @@ -44,7 +51,7 @@ 6.31 6.32 isGCActiveMark.hpp parallelScavengeHeap.hpp 6.33 6.34 -markSweep.inline.hpp psParallelCompact.hpp 6.35 +markSweep.inline.hpp psParallelCompact.hpp 6.36 6.37 mutableNUMASpace.cpp mutableNUMASpace.hpp 6.38 mutableNUMASpace.cpp sharedHeap.hpp
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/share/vm/gc_implementation/shared/allocationStats.cpp Fri Feb 29 14:42:56 2008 -0800 7.3 @@ -0,0 +1,30 @@ 7.4 +/* 7.5 + * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. 7.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 + * 7.8 + * This code is free software; you can redistribute it and/or modify it 7.9 + * under the terms of the GNU General Public License version 2 only, as 7.10 + * published by the Free Software Foundation. 7.11 + * 7.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.15 + * version 2 for more details (a copy is included in the LICENSE file that 7.16 + * accompanied this code). 7.17 + * 7.18 + * You should have received a copy of the GNU General Public License version 7.19 + * 2 along with this work; if not, write to the Free Software Foundation, 7.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.21 + * 7.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 7.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 7.24 + * have any questions. 7.25 + * 7.26 + */ 7.27 + 7.28 +# include "incls/_precompiled.incl" 7.29 +# include "incls/_allocationStats.cpp.incl" 7.30 + 7.31 +// Technically this should be derived from machine speed, and 7.32 +// ideally it would be dynamically adjusted. 7.33 +float AllocationStats::_threshold = ((float)CMS_SweepTimerThresholdMillis)/1000;
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/share/vm/gc_implementation/shared/allocationStats.hpp Fri Feb 29 14:42:56 2008 -0800 8.3 @@ -0,0 +1,138 @@ 8.4 +/* 8.5 + * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. 8.11 + * 8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.15 + * version 2 for more details (a copy is included in the LICENSE file that 8.16 + * accompanied this code). 8.17 + * 8.18 + * You should have received a copy of the GNU General Public License version 8.19 + * 2 along with this work; if not, write to the Free Software Foundation, 8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.21 + * 8.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 8.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 8.24 + * have any questions. 8.25 + * 8.26 + */ 8.27 + 8.28 +class AllocationStats VALUE_OBJ_CLASS_SPEC { 8.29 + // A duration threshold (in ms) used to filter 8.30 + // possibly unreliable samples. 8.31 + static float _threshold; 8.32 + 8.33 + // We measure the demand between the end of the previous sweep and 8.34 + // beginning of this sweep: 8.35 + // Count(end_last_sweep) - Count(start_this_sweep) 8.36 + // + splitBirths(between) - splitDeaths(between) 8.37 + // The above number divided by the time since the start [END???] of the 8.38 + // previous sweep gives us a time rate of demand for blocks 8.39 + // of this size. We compute a padded average of this rate as 8.40 + // our current estimate for the time rate of demand for blocks 8.41 + // of this size. Similarly, we keep a padded average for the time 8.42 + // between sweeps. Our current estimate for demand for blocks of 8.43 + // this size is then simply computed as the product of these two 8.44 + // estimates. 8.45 + AdaptivePaddedAverage _demand_rate_estimate; 8.46 + 8.47 + ssize_t _desired; // Estimate computed as described above 8.48 + ssize_t _coalDesired; // desired +/- small-percent for tuning coalescing 8.49 + 8.50 + ssize_t _surplus; // count - (desired +/- small-percent), 8.51 + // used to tune splitting in best fit 8.52 + ssize_t _bfrSurp; // surplus at start of current sweep 8.53 + ssize_t _prevSweep; // count from end of previous sweep 8.54 + ssize_t _beforeSweep; // count from before current sweep 8.55 + ssize_t _coalBirths; // additional chunks from coalescing 8.56 + ssize_t _coalDeaths; // loss from coalescing 8.57 + ssize_t _splitBirths; // additional chunks from splitting 8.58 + ssize_t _splitDeaths; // loss from splitting 8.59 + size_t _returnedBytes; // number of bytes returned to list. 8.60 + public: 8.61 + void initialize() { 8.62 + AdaptivePaddedAverage* dummy = 8.63 + new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight, 8.64 + CMS_FLSPadding); 8.65 + _desired = 0; 8.66 + _coalDesired = 0; 8.67 + _surplus = 0; 8.68 + _bfrSurp = 0; 8.69 + _prevSweep = 0; 8.70 + _beforeSweep = 0; 8.71 + _coalBirths = 0; 8.72 + _coalDeaths = 0; 8.73 + _splitBirths = 0; 8.74 + _splitDeaths = 0; 8.75 + _returnedBytes = 0; 8.76 + } 8.77 + 8.78 + AllocationStats() { 8.79 + initialize(); 8.80 + } 8.81 + // The rate estimate is in blocks per second. 8.82 + void compute_desired(size_t count, 8.83 + float inter_sweep_current, 8.84 + float inter_sweep_estimate) { 8.85 + // If the latest inter-sweep time is below our granularity 8.86 + // of measurement, we may call in here with 8.87 + // inter_sweep_current == 0. However, even for suitably small 8.88 + // but non-zero inter-sweep durations, we may not trust the accuracy 8.89 + // of accumulated data, since it has not been "integrated" 8.90 + // (read "low-pass-filtered") long enough, and would be 8.91 + // vulnerable to noisy glitches. In such cases, we 8.92 + // ignore the current sample and use currently available 8.93 + // historical estimates. 8.94 + if (inter_sweep_current > _threshold) { 8.95 + ssize_t demand = prevSweep() - count + splitBirths() - splitDeaths(); 8.96 + float rate = ((float)demand)/inter_sweep_current; 8.97 + _demand_rate_estimate.sample(rate); 8.98 + _desired = (ssize_t)(_demand_rate_estimate.padded_average() 8.99 + *inter_sweep_estimate); 8.100 + } 8.101 + } 8.102 + 8.103 + ssize_t desired() const { return _desired; } 8.104 + void set_desired(ssize_t v) { _desired = v; } 8.105 + 8.106 + ssize_t coalDesired() const { return _coalDesired; } 8.107 + void set_coalDesired(ssize_t v) { _coalDesired = v; } 8.108 + 8.109 + ssize_t surplus() const { return _surplus; } 8.110 + void set_surplus(ssize_t v) { _surplus = v; } 8.111 + void increment_surplus() { _surplus++; } 8.112 + void decrement_surplus() { _surplus--; } 8.113 + 8.114 + ssize_t bfrSurp() const { return _bfrSurp; } 8.115 + void set_bfrSurp(ssize_t v) { _bfrSurp = v; } 8.116 + ssize_t prevSweep() const { return _prevSweep; } 8.117 + void set_prevSweep(ssize_t v) { _prevSweep = v; } 8.118 + ssize_t beforeSweep() const { return _beforeSweep; } 8.119 + void set_beforeSweep(ssize_t v) { _beforeSweep = v; } 8.120 + 8.121 + ssize_t coalBirths() const { return _coalBirths; } 8.122 + void set_coalBirths(ssize_t v) { _coalBirths = v; } 8.123 + void increment_coalBirths() { _coalBirths++; } 8.124 + 8.125 + ssize_t coalDeaths() const { return _coalDeaths; } 8.126 + void set_coalDeaths(ssize_t v) { _coalDeaths = v; } 8.127 + void increment_coalDeaths() { _coalDeaths++; } 8.128 + 8.129 + ssize_t splitBirths() const { return _splitBirths; } 8.130 + void set_splitBirths(ssize_t v) { _splitBirths = v; } 8.131 + void increment_splitBirths() { _splitBirths++; } 8.132 + 8.133 + ssize_t splitDeaths() const { return _splitDeaths; } 8.134 + void set_splitDeaths(ssize_t v) { _splitDeaths = v; } 8.135 + void increment_splitDeaths() { _splitDeaths++; } 8.136 + 8.137 + NOT_PRODUCT( 8.138 + size_t returnedBytes() const { return _returnedBytes; } 8.139 + void set_returnedBytes(size_t v) { _returnedBytes = v; } 8.140 + ) 8.141 +};
9.1 --- a/src/share/vm/includeDB_core Tue Feb 26 15:57:49 2008 -0800 9.2 +++ b/src/share/vm/includeDB_core Fri Feb 29 14:42:56 2008 -0800 9.3 @@ -19,7 +19,7 @@ 9.4 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 9.5 // CA 95054 USA or visit www.sun.com if you need additional information or 9.6 // have any questions. 9.7 -// 9.8 +// 9.9 // 9.10 9.11 // NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! 9.12 @@ -46,13 +46,13 @@ 9.13 // as dependencies. Header files named H.inline.hpp generally contain 9.14 // bodies for inline functions declared in H.hpp. 9.15 // 9.16 -// NOTE: Files that use the token "generate_platform_dependent_include" 9.17 +// NOTE: Files that use the token "generate_platform_dependent_include" 9.18 // are expected to contain macro references like <os>, <arch_model>, ... and 9.19 // makedeps has a dependency on these platform files looking like: 9.20 -// foo_<macro>.trailing_string 9.21 +// foo_<macro>.trailing_string 9.22 // (where "trailing_string" can be any legal filename strings but typically 9.23 // is "hpp" or "inline.hpp"). 9.24 -// 9.25 +// 9.26 // The dependency in makedeps (and enforced) is that an underscore 9.27 // will precedure the macro invocation. Note that this restriction 9.28 // is only enforced on filenames that have the dependency token 9.29 @@ -148,12 +148,6 @@ 9.30 9.31 allocation.inline.hpp os.hpp 9.32 9.33 -allocationStats.cpp allocationStats.hpp 9.34 - 9.35 -allocationStats.hpp allocation.hpp 9.36 -allocationStats.hpp gcUtil.hpp 9.37 -allocationStats.hpp globalDefinitions.hpp 9.38 - 9.39 aprofiler.cpp aprofiler.hpp 9.40 aprofiler.cpp collectedHeap.inline.hpp 9.41 aprofiler.cpp oop.inline.hpp 9.42 @@ -1935,7 +1929,7 @@ 9.43 9.44 init.cpp bytecodes.hpp 9.45 init.cpp collectedHeap.hpp 9.46 -init.cpp handles.inline.hpp 9.47 +init.cpp handles.inline.hpp 9.48 init.cpp icBuffer.hpp 9.49 init.cpp icache.hpp 9.50 init.cpp init.hpp
10.1 --- a/src/share/vm/memory/allocationStats.cpp Tue Feb 26 15:57:49 2008 -0800 10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 10.3 @@ -1,30 +0,0 @@ 10.4 -/* 10.5 - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. 10.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.7 - * 10.8 - * This code is free software; you can redistribute it and/or modify it 10.9 - * under the terms of the GNU General Public License version 2 only, as 10.10 - * published by the Free Software Foundation. 10.11 - * 10.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 10.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 10.15 - * version 2 for more details (a copy is included in the LICENSE file that 10.16 - * accompanied this code). 10.17 - * 10.18 - * You should have received a copy of the GNU General Public License version 10.19 - * 2 along with this work; if not, write to the Free Software Foundation, 10.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 10.21 - * 10.22 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 10.23 - * CA 95054 USA or visit www.sun.com if you need additional information or 10.24 - * have any questions. 10.25 - * 10.26 - */ 10.27 - 10.28 -# include "incls/_precompiled.incl" 10.29 -# include "incls/_allocationStats.cpp.incl" 10.30 - 10.31 -// Technically this should be derived from machine speed, and 10.32 -// ideally it would be dynamically adjusted. 10.33 -float AllocationStats::_threshold = ((float)CMS_SweepTimerThresholdMillis)/1000;
11.1 --- a/src/share/vm/memory/allocationStats.hpp Tue Feb 26 15:57:49 2008 -0800 11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 11.3 @@ -1,136 +0,0 @@ 11.4 -/* 11.5 - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. 11.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 - * 11.8 - * This code is free software; you can redistribute it and/or modify it 11.9 - * under the terms of the GNU General Public License version 2 only, as 11.10 - * published by the Free Software Foundation. 11.11 - * 11.12 - * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 - * version 2 for more details (a copy is included in the LICENSE file that 11.16 - * accompanied this code). 11.17 - * 11.18 - * You should have received a copy of the GNU General Public License version 11.19 - * 2 along with this work; if not, write to the Free Software Foundation, 11.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 - * 11.22 - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 11.23 - * CA 95054 USA or visit www.sun.com if you need additional information or 11.24 - * have any questions. 11.25 - * 11.26 - */ 11.27 - 11.28 -class AllocationStats VALUE_OBJ_CLASS_SPEC { 11.29 - // A duration threshold (in ms) used to filter 11.30 - // possibly unreliable samples. 11.31 - static float _threshold; 11.32 - 11.33 - // We measure the demand between the end of the previous sweep and 11.34 - // beginning of this sweep: 11.35 - // Count(end_last_sweep) - Count(start_this_sweep) 11.36 - // + splitBirths(between) - splitDeaths(between) 11.37 - // The above number divided by the time since the start [END???] of the 11.38 - // previous sweep gives us a time rate of demand for blocks 11.39 - // of this size. We compute a padded average of this rate as 11.40 - // our current estimate for the time rate of demand for blocks 11.41 - // of this size. Similarly, we keep a padded average for the time 11.42 - // between sweeps. Our current estimate for demand for blocks of 11.43 - // this size is then simply computed as the product of these two 11.44 - // estimates. 11.45 - AdaptivePaddedAverage _demand_rate_estimate; 11.46 - 11.47 - ssize_t _desired; // Estimate computed as described above 11.48 - ssize_t _coalDesired; // desired +/- small-percent for tuning coalescing 11.49 - 11.50 - ssize_t _surplus; // count - (desired +/- small-percent), 11.51 - // used to tune splitting in best fit 11.52 - ssize_t _bfrSurp; // surplus at start of current sweep 11.53 - ssize_t _prevSweep; // count from end of previous sweep 11.54 - ssize_t _beforeSweep; // count from before current sweep 11.55 - ssize_t _coalBirths; // additional chunks from coalescing 11.56 - ssize_t _coalDeaths; // loss from coalescing 11.57 - ssize_t _splitBirths; // additional chunks from splitting 11.58 - ssize_t _splitDeaths; // loss from splitting 11.59 - size_t _returnedBytes; // number of bytes returned to list. 11.60 - public: 11.61 - void initialize() { 11.62 - AdaptivePaddedAverage* dummy = 11.63 - new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight, 11.64 - CMS_FLSPadding); 11.65 - _desired = 0; 11.66 - _coalDesired = 0; 11.67 - _surplus = 0; 11.68 - _bfrSurp = 0; 11.69 - _prevSweep = 0; 11.70 - _beforeSweep = 0; 11.71 - _coalBirths = 0; 11.72 - _coalDeaths = 0; 11.73 - _splitBirths = 0; 11.74 - _splitDeaths = 0; 11.75 - _returnedBytes = 0; 11.76 - } 11.77 - 11.78 - AllocationStats() { 11.79 - initialize(); 11.80 - } 11.81 - // The rate estimate is in blocks per second. 11.82 - void compute_desired(size_t count, 11.83 - float inter_sweep_current, 11.84 - float inter_sweep_estimate) { 11.85 - // If the latest inter-sweep time is below our granularity 11.86 - // of measurement, we may call in here with 11.87 - // inter_sweep_current == 0. However, even for suitably small 11.88 - // but non-zero inter-sweep durations, we may not trust the accuracy 11.89 - // of accumulated data, since it has not been "integrated" 11.90 - // (read "low-pass-filtered") long enough, and would be 11.91 - // vulnerable to noisy glitches. In such cases, we 11.92 - // ignore the current sample and use currently available 11.93 - // historical estimates. 11.94 - if (inter_sweep_current > _threshold) { 11.95 - ssize_t demand = prevSweep() - count + splitBirths() - splitDeaths(); 11.96 - float rate = ((float)demand)/inter_sweep_current; 11.97 - _demand_rate_estimate.sample(rate); 11.98 - _desired = (ssize_t)(_demand_rate_estimate.padded_average() 11.99 - *inter_sweep_estimate); 11.100 - } 11.101 - } 11.102 - 11.103 - ssize_t desired() const { return _desired; } 11.104 - ssize_t coalDesired() const { return _coalDesired; } 11.105 - void set_coalDesired(ssize_t v) { _coalDesired = v; } 11.106 - 11.107 - ssize_t surplus() const { return _surplus; } 11.108 - void set_surplus(ssize_t v) { _surplus = v; } 11.109 - void increment_surplus() { _surplus++; } 11.110 - void decrement_surplus() { _surplus--; } 11.111 - 11.112 - ssize_t bfrSurp() const { return _bfrSurp; } 11.113 - void set_bfrSurp(ssize_t v) { _bfrSurp = v; } 11.114 - ssize_t prevSweep() const { return _prevSweep; } 11.115 - void set_prevSweep(ssize_t v) { _prevSweep = v; } 11.116 - ssize_t beforeSweep() const { return _beforeSweep; } 11.117 - void set_beforeSweep(ssize_t v) { _beforeSweep = v; } 11.118 - 11.119 - ssize_t coalBirths() const { return _coalBirths; } 11.120 - void set_coalBirths(ssize_t v) { _coalBirths = v; } 11.121 - void increment_coalBirths() { _coalBirths++; } 11.122 - 11.123 - ssize_t coalDeaths() const { return _coalDeaths; } 11.124 - void set_coalDeaths(ssize_t v) { _coalDeaths = v; } 11.125 - void increment_coalDeaths() { _coalDeaths++; } 11.126 - 11.127 - ssize_t splitBirths() const { return _splitBirths; } 11.128 - void set_splitBirths(ssize_t v) { _splitBirths = v; } 11.129 - void increment_splitBirths() { _splitBirths++; } 11.130 - 11.131 - ssize_t splitDeaths() const { return _splitDeaths; } 11.132 - void set_splitDeaths(ssize_t v) { _splitDeaths = v; } 11.133 - void increment_splitDeaths() { _splitDeaths++; } 11.134 - 11.135 - NOT_PRODUCT( 11.136 - size_t returnedBytes() const { return _returnedBytes; } 11.137 - void set_returnedBytes(size_t v) { _returnedBytes = v; } 11.138 - ) 11.139 -};