1054 // Print summary statistics 1055 void BinaryTreeDictionary::reportStatistics() const { 1056 verify_par_locked(); 1057 gclog_or_tty->print("Statistics for BinaryTreeDictionary:\n" 1058 "------------------------------------\n"); 1059 size_t totalSize = totalChunkSize(debug_only(NULL)); 1060 size_t freeBlocks = numFreeBlocks(); 1061 gclog_or_tty->print("Total Free Space: %d\n", totalSize); 1062 gclog_or_tty->print("Max Chunk Size: %d\n", maxChunkSize()); 1063 gclog_or_tty->print("Number of Blocks: %d\n", freeBlocks); 1064 if (freeBlocks > 0) { 1065 gclog_or_tty->print("Av. Block Size: %d\n", totalSize/freeBlocks); 1066 } 1067 gclog_or_tty->print("Tree Height: %d\n", treeHeight()); 1068 } 1069 1070 // Print census information - counts, births, deaths, etc. 1071 // for each list in the tree. Also print some summary 1072 // information. 1073 class printTreeCensusClosure : public AscendTreeCensusClosure { 1074 size_t _totalFree; 1075 AllocationStats _totals; 1076 size_t _count; 1077 1078 public: 1079 printTreeCensusClosure() { 1080 _totalFree = 0; 1081 _count = 0; 1082 _totals.initialize(); 1083 } 1084 AllocationStats* totals() { return &_totals; } 1085 size_t count() { return _count; } 1086 void increment_count_by(size_t v) { _count += v; } 1087 size_t totalFree() { return _totalFree; } 1088 void increment_totalFree_by(size_t v) { _totalFree += v; } 1089 void do_list(FreeList* fl) { 1090 bool nl = false; // "maybe this is not needed" isNearLargestChunk(fl->head()); 1091 1092 gclog_or_tty->print("%c %4d\t\t" "%7d\t" "%7d\t" 1093 "%7d\t" "%7d\t" "%7d\t" "%7d\t" 1094 "%7d\t" "%7d\t" "%7d\t" 1095 "%7d\t" "\n", 1096 " n"[nl], fl->size(), fl->bfrSurp(), fl->surplus(), 1097 fl->desired(), fl->prevSweep(), fl->beforeSweep(), fl->count(), 1098 fl->coalBirths(), fl->coalDeaths(), fl->splitBirths(), 1099 fl->splitDeaths()); 1100 1101 increment_totalFree_by(fl->count() * fl->size()); 1102 increment_count_by(fl->count()); 1103 totals()->set_bfrSurp(totals()->bfrSurp() + fl->bfrSurp()); 1104 totals()->set_surplus(totals()->splitDeaths() + fl->surplus()); 1105 totals()->set_prevSweep(totals()->prevSweep() + fl->prevSweep()); 1106 totals()->set_beforeSweep(totals()->beforeSweep() + fl->beforeSweep()); 1107 totals()->set_coalBirths(totals()->coalBirths() + fl->coalBirths()); 1108 totals()->set_coalDeaths(totals()->coalDeaths() + fl->coalDeaths()); 1109 totals()->set_splitBirths(totals()->splitBirths() + fl->splitBirths()); 1110 totals()->set_splitDeaths(totals()->splitDeaths() + fl->splitDeaths()); 1111 } 1112 }; 1113 1114 void BinaryTreeDictionary::printDictCensus(void) const { 1115 1116 gclog_or_tty->print("\nBinaryTree\n"); 1117 gclog_or_tty->print( 1118 "%4s\t\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" 1119 "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "\n", 1120 "size", "bfrsurp", "surplus", "desired", "prvSwep", "bfrSwep", 1121 "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); 1122 1123 printTreeCensusClosure ptc; 1124 ptc.do_tree(root()); 1125 1126 gclog_or_tty->print( 1127 "\t\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" 1128 "%7s\t" "%7s\t" "%7s\t" "%7s\t" "%7s\t" "\n", 1129 "bfrsurp", "surplus", "prvSwep", "bfrSwep", 1130 "count", "cBirths", "cDeaths", "sBirths", "sDeaths"); 1131 gclog_or_tty->print( 1132 "%s\t\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" 1133 "%7d\t" "%7d\t" "%7d\t" "%7d\t" "%7d\t" "\n", 1134 "totl", 1135 ptc.totals()->bfrSurp(), 1136 ptc.totals()->surplus(), 1137 ptc.totals()->prevSweep(), 1138 ptc.totals()->beforeSweep(), 1139 ptc.count(), 1140 ptc.totals()->coalBirths(), 1141 ptc.totals()->coalDeaths(), 1142 ptc.totals()->splitBirths(), 1143 ptc.totals()->splitDeaths()); 1144 gclog_or_tty->print("totalFree(words): %7d growth: %8.5f deficit: %8.5f\n", 1145 ptc.totalFree(), 1146 (double)(ptc.totals()->splitBirths()+ptc.totals()->coalBirths() 1147 -ptc.totals()->splitDeaths()-ptc.totals()->coalDeaths()) 1148 /(ptc.totals()->prevSweep() != 0 ? 1149 (double)ptc.totals()->prevSweep() : 1.0), 1150 (double)(ptc.totals()->desired() - ptc.count()) 1151 /(ptc.totals()->desired() != 0 ? 1152 (double)ptc.totals()->desired() : 1.0)); 1153 } 1154 1155 // Verify the following tree invariants: 1156 // . _root has no parent 1157 // . parent and child point to each other 1158 // . each node's key correctly related to that of its child(ren) 1159 void BinaryTreeDictionary::verifyTree() const { 1160 guarantee(root() == NULL || totalFreeBlocks() == 0 || 1161 totalSize() != 0, "_totalSize should't be 0?"); 1162 guarantee(root() == NULL || root()->parent() == NULL, "_root shouldn't have parent"); 1163 verifyTreeHelper(root()); 1164 } 1165 1166 size_t BinaryTreeDictionary::verifyPrevFreePtrs(TreeList* tl) { 1167 size_t ct = 0; 1168 for (FreeChunk* curFC = tl->head(); curFC != NULL; curFC = curFC->next()) { 1169 ct++; 1170 assert(curFC->prev() == NULL || curFC->prev()->isFree(), 1171 "Chunk should be free"); 1172 } | 1054 // Print summary statistics 1055 void BinaryTreeDictionary::reportStatistics() const { 1056 verify_par_locked(); 1057 gclog_or_tty->print("Statistics for BinaryTreeDictionary:\n" 1058 "------------------------------------\n"); 1059 size_t totalSize = totalChunkSize(debug_only(NULL)); 1060 size_t freeBlocks = numFreeBlocks(); 1061 gclog_or_tty->print("Total Free Space: %d\n", totalSize); 1062 gclog_or_tty->print("Max Chunk Size: %d\n", maxChunkSize()); 1063 gclog_or_tty->print("Number of Blocks: %d\n", freeBlocks); 1064 if (freeBlocks > 0) { 1065 gclog_or_tty->print("Av. Block Size: %d\n", totalSize/freeBlocks); 1066 } 1067 gclog_or_tty->print("Tree Height: %d\n", treeHeight()); 1068 } 1069 1070 // Print census information - counts, births, deaths, etc. 1071 // for each list in the tree. Also print some summary 1072 // information. 1073 class printTreeCensusClosure : public AscendTreeCensusClosure { 1074 int _print_line; 1075 size_t _totalFree; 1076 FreeList _total; 1077 1078 public: 1079 printTreeCensusClosure() { 1080 _print_line = 0; 1081 _totalFree = 0; 1082 } 1083 FreeList* total() { return &_total; } 1084 size_t totalFree() { return _totalFree; } 1085 void do_list(FreeList* fl) { 1086 if (++_print_line >= 40) { 1087 FreeList::print_labels_on(gclog_or_tty, "size"); 1088 _print_line = 0; 1089 } 1090 fl->print_on(gclog_or_tty); 1091 _totalFree += fl->count() * fl->size() ; 1092 total()->set_count( total()->count() + fl->count() ); 1093 total()->set_bfrSurp( total()->bfrSurp() + fl->bfrSurp() ); 1094 total()->set_surplus( total()->splitDeaths() + fl->surplus() ); 1095 total()->set_desired( total()->desired() + fl->desired() ); 1096 total()->set_prevSweep( total()->prevSweep() + fl->prevSweep() ); 1097 total()->set_beforeSweep(total()->beforeSweep() + fl->beforeSweep()); 1098 total()->set_coalBirths( total()->coalBirths() + fl->coalBirths() ); 1099 total()->set_coalDeaths( total()->coalDeaths() + fl->coalDeaths() ); 1100 total()->set_splitBirths(total()->splitBirths() + fl->splitBirths()); 1101 total()->set_splitDeaths(total()->splitDeaths() + fl->splitDeaths()); 1102 } 1103 }; 1104 1105 void BinaryTreeDictionary::printDictCensus(void) const { 1106 1107 gclog_or_tty->print("\nBinaryTree\n"); 1108 FreeList::print_labels_on(gclog_or_tty, "size"); 1109 printTreeCensusClosure ptc; 1110 ptc.do_tree(root()); 1111 1112 FreeList* total = ptc.total(); 1113 FreeList::print_labels_on(gclog_or_tty, " "); 1114 total->print_on(gclog_or_tty, "TOTAL\t"); 1115 gclog_or_tty->print( 1116 "totalFree(words): " SIZE_FORMAT_W(16) 1117 " growth: %8.5f deficit: %8.5f\n", 1118 ptc.totalFree(), 1119 (double)(total->splitBirths() + total->coalBirths() 1120 - total->splitDeaths() - total->coalDeaths()) 1121 /(total->prevSweep() != 0 ? (double)total->prevSweep() : 1.0), 1122 (double)(total->desired() - total->count()) 1123 /(total->desired() != 0 ? (double)total->desired() : 1.0)); 1124 } 1125 1126 // Verify the following tree invariants: 1127 // . _root has no parent 1128 // . parent and child point to each other 1129 // . each node's key correctly related to that of its child(ren) 1130 void BinaryTreeDictionary::verifyTree() const { 1131 guarantee(root() == NULL || totalFreeBlocks() == 0 || 1132 totalSize() != 0, "_totalSize should't be 0?"); 1133 guarantee(root() == NULL || root()->parent() == NULL, "_root shouldn't have parent"); 1134 verifyTreeHelper(root()); 1135 } 1136 1137 size_t BinaryTreeDictionary::verifyPrevFreePtrs(TreeList* tl) { 1138 size_t ct = 0; 1139 for (FreeChunk* curFC = tl->head(); curFC != NULL; curFC = curFC->next()) { 1140 ct++; 1141 assert(curFC->prev() == NULL || curFC->prev()->isFree(), 1142 "Chunk should be free"); 1143 } |