1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp Wed Dec 16 15:12:51 2009 -0800 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp Wed Dec 23 09:23:54 2009 -0800 1.3 @@ -62,12 +62,13 @@ 1.4 tl->link_head(tc); 1.5 tl->link_tail(tc); 1.6 tl->set_count(1); 1.7 - tl->init_statistics(); 1.8 + tl->init_statistics(true /* split_birth */); 1.9 tl->setParent(NULL); 1.10 tl->setLeft(NULL); 1.11 tl->setRight(NULL); 1.12 return tl; 1.13 } 1.14 + 1.15 TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) { 1.16 TreeChunk* tc = (TreeChunk*) addr; 1.17 assert(size >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk"); 1.18 @@ -267,6 +268,31 @@ 1.19 return retTC; 1.20 } 1.21 1.22 +// Returns the block with the largest heap address amongst 1.23 +// those in the list for this size; potentially slow and expensive, 1.24 +// use with caution! 1.25 +TreeChunk* TreeList::largest_address() { 1.26 + guarantee(head() != NULL, "The head of the list cannot be NULL"); 1.27 + FreeChunk* fc = head()->next(); 1.28 + TreeChunk* retTC; 1.29 + if (fc == NULL) { 1.30 + retTC = head_as_TreeChunk(); 1.31 + } else { 1.32 + // walk down the list and return the one with the highest 1.33 + // heap address among chunks of this size. 1.34 + FreeChunk* last = fc; 1.35 + while (fc->next() != NULL) { 1.36 + if ((HeapWord*)last < (HeapWord*)fc) { 1.37 + last = fc; 1.38 + } 1.39 + fc = fc->next(); 1.40 + } 1.41 + retTC = TreeChunk::as_TreeChunk(last); 1.42 + } 1.43 + assert(retTC->list() == this, "Wrong type of chunk."); 1.44 + return retTC; 1.45 +} 1.46 + 1.47 BinaryTreeDictionary::BinaryTreeDictionary(MemRegion mr, bool splay): 1.48 _splay(splay) 1.49 { 1.50 @@ -379,7 +405,7 @@ 1.51 break; 1.52 } 1.53 // The evm code reset the hint of the candidate as 1.54 - // at an interrim point. Why? Seems like this leaves 1.55 + // at an interim point. Why? Seems like this leaves 1.56 // the hint pointing to a list that didn't work. 1.57 // curTL->set_hint(hintTL->size()); 1.58 } 1.59 @@ -436,7 +462,7 @@ 1.60 TreeList *curTL = root(); 1.61 if (curTL != NULL) { 1.62 while(curTL->right() != NULL) curTL = curTL->right(); 1.63 - return curTL->first_available(); 1.64 + return curTL->largest_address(); 1.65 } else { 1.66 return NULL; 1.67 } 1.68 @@ -664,7 +690,7 @@ 1.69 } 1.70 } 1.71 TreeChunk* tc = TreeChunk::as_TreeChunk(fc); 1.72 - // This chunk is being returned to the binary try. It's embedded 1.73 + // This chunk is being returned to the binary tree. Its embedded 1.74 // TreeList should be unused at this point. 1.75 tc->initialize(); 1.76 if (curTL != NULL) { // exact match 1.77 @@ -807,6 +833,8 @@ 1.78 } 1.79 1.80 bool BinaryTreeDictionary::coalDictOverPopulated(size_t size) { 1.81 + if (FLSAlwaysCoalesceLarge) return true; 1.82 + 1.83 TreeList* list_of_size = findList(size); 1.84 // None of requested size implies overpopulated. 1.85 return list_of_size == NULL || list_of_size->coalDesired() <= 0 || 1.86 @@ -854,17 +882,20 @@ 1.87 double _percentage; 1.88 float _inter_sweep_current; 1.89 float _inter_sweep_estimate; 1.90 + float _intra_sweep_estimate; 1.91 1.92 public: 1.93 BeginSweepClosure(double p, float inter_sweep_current, 1.94 - float inter_sweep_estimate) : 1.95 + float inter_sweep_estimate, 1.96 + float intra_sweep_estimate) : 1.97 _percentage(p), 1.98 _inter_sweep_current(inter_sweep_current), 1.99 - _inter_sweep_estimate(inter_sweep_estimate) { } 1.100 + _inter_sweep_estimate(inter_sweep_estimate), 1.101 + _intra_sweep_estimate(intra_sweep_estimate) { } 1.102 1.103 void do_list(FreeList* fl) { 1.104 double coalSurplusPercent = _percentage; 1.105 - fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate); 1.106 + fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate, _intra_sweep_estimate); 1.107 fl->set_coalDesired((ssize_t)((double)fl->desired() * coalSurplusPercent)); 1.108 fl->set_beforeSweep(fl->count()); 1.109 fl->set_bfrSurp(fl->surplus()); 1.110 @@ -939,9 +970,10 @@ 1.111 } 1.112 1.113 void BinaryTreeDictionary::beginSweepDictCensus(double coalSurplusPercent, 1.114 - float inter_sweep_current, float inter_sweep_estimate) { 1.115 + float inter_sweep_current, float inter_sweep_estimate, float intra_sweep_estimate) { 1.116 BeginSweepClosure bsc(coalSurplusPercent, inter_sweep_current, 1.117 - inter_sweep_estimate); 1.118 + inter_sweep_estimate, 1.119 + intra_sweep_estimate); 1.120 bsc.do_tree(root()); 1.121 } 1.122 1.123 @@ -1077,13 +1109,13 @@ 1.124 // Print census information - counts, births, deaths, etc. 1.125 // for each list in the tree. Also print some summary 1.126 // information. 1.127 -class printTreeCensusClosure : public AscendTreeCensusClosure { 1.128 +class PrintTreeCensusClosure : public AscendTreeCensusClosure { 1.129 int _print_line; 1.130 size_t _totalFree; 1.131 FreeList _total; 1.132 1.133 public: 1.134 - printTreeCensusClosure() { 1.135 + PrintTreeCensusClosure() { 1.136 _print_line = 0; 1.137 _totalFree = 0; 1.138 } 1.139 @@ -1113,7 +1145,7 @@ 1.140 1.141 gclog_or_tty->print("\nBinaryTree\n"); 1.142 FreeList::print_labels_on(gclog_or_tty, "size"); 1.143 - printTreeCensusClosure ptc; 1.144 + PrintTreeCensusClosure ptc; 1.145 ptc.do_tree(root()); 1.146 1.147 FreeList* total = ptc.total(); 1.148 @@ -1130,6 +1162,38 @@ 1.149 /(total->desired() != 0 ? (double)total->desired() : 1.0)); 1.150 } 1.151 1.152 +class PrintFreeListsClosure : public AscendTreeCensusClosure { 1.153 + outputStream* _st; 1.154 + int _print_line; 1.155 + 1.156 + public: 1.157 + PrintFreeListsClosure(outputStream* st) { 1.158 + _st = st; 1.159 + _print_line = 0; 1.160 + } 1.161 + void do_list(FreeList* fl) { 1.162 + if (++_print_line >= 40) { 1.163 + FreeList::print_labels_on(_st, "size"); 1.164 + _print_line = 0; 1.165 + } 1.166 + fl->print_on(gclog_or_tty); 1.167 + size_t sz = fl->size(); 1.168 + for (FreeChunk* fc = fl->head(); fc != NULL; 1.169 + fc = fc->next()) { 1.170 + _st->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", 1.171 + fc, (HeapWord*)fc + sz, 1.172 + fc->cantCoalesce() ? "\t CC" : ""); 1.173 + } 1.174 + } 1.175 +}; 1.176 + 1.177 +void BinaryTreeDictionary::print_free_lists(outputStream* st) const { 1.178 + 1.179 + FreeList::print_labels_on(st, "size"); 1.180 + PrintFreeListsClosure pflc(st); 1.181 + pflc.do_tree(root()); 1.182 +} 1.183 + 1.184 // Verify the following tree invariants: 1.185 // . _root has no parent 1.186 // . parent and child point to each other