1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Apr 20 17:13:36 2012 -0700 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Mar 29 19:46:24 2012 -0700 1.3 @@ -69,7 +69,7 @@ 1.4 // Constructor 1.5 CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, 1.6 MemRegion mr, bool use_adaptive_freelists, 1.7 - FreeBlockDictionary::DictionaryChoice dictionaryChoice) : 1.8 + FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) : 1.9 _dictionaryChoice(dictionaryChoice), 1.10 _adaptive_freelists(use_adaptive_freelists), 1.11 _bt(bs, mr), 1.12 @@ -87,6 +87,8 @@ 1.13 CMSConcMarkMultiple), 1.14 _collector(NULL) 1.15 { 1.16 + assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize, 1.17 + "FreeChunk is larger than expected"); 1.18 _bt.set_space(this); 1.19 initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); 1.20 // We have all of "mr", all of which we place in the dictionary 1.21 @@ -96,13 +98,13 @@ 1.22 // implementation, namely, the simple binary tree (splaying 1.23 // temporarily disabled). 1.24 switch (dictionaryChoice) { 1.25 - case FreeBlockDictionary::dictionarySplayTree: 1.26 - case FreeBlockDictionary::dictionarySkipList: 1.27 + case FreeBlockDictionary<FreeChunk>::dictionarySplayTree: 1.28 + case FreeBlockDictionary<FreeChunk>::dictionarySkipList: 1.29 default: 1.30 warning("dictionaryChoice: selected option not understood; using" 1.31 " default BinaryTreeDictionary implementation instead."); 1.32 - case FreeBlockDictionary::dictionaryBinaryTree: 1.33 - _dictionary = new BinaryTreeDictionary(mr); 1.34 + case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree: 1.35 + _dictionary = new BinaryTreeDictionary<FreeChunk>(mr, use_adaptive_freelists); 1.36 break; 1.37 } 1.38 assert(_dictionary != NULL, "CMS dictionary initialization"); 1.39 @@ -448,7 +450,7 @@ 1.40 reportIndexedFreeListStatistics(); 1.41 gclog_or_tty->print_cr("Layout of Indexed Freelists"); 1.42 gclog_or_tty->print_cr("---------------------------"); 1.43 - FreeList::print_labels_on(st, "size"); 1.44 + FreeList<FreeChunk>::print_labels_on(st, "size"); 1.45 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 1.46 _indexedFreeList[i].print_on(gclog_or_tty); 1.47 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; 1.48 @@ -1331,7 +1333,7 @@ 1.49 size_t currSize = numWords + MinChunkSize; 1.50 assert(currSize % MinObjAlignment == 0, "currSize should be aligned"); 1.51 for (i = currSize; i < IndexSetSize; i += IndexSetStride) { 1.52 - FreeList* fl = &_indexedFreeList[i]; 1.53 + FreeList<FreeChunk>* fl = &_indexedFreeList[i]; 1.54 if (fl->head()) { 1.55 ret = getFromListGreater(fl, numWords); 1.56 assert(ret == NULL || ret->isFree(), "Should be returning a free chunk"); 1.57 @@ -1714,7 +1716,7 @@ 1.58 _dictionary->returnChunk(chunk); 1.59 #ifndef PRODUCT 1.60 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) { 1.61 - TreeChunk::as_TreeChunk(chunk)->list()->verify_stats(); 1.62 + TreeChunk<FreeChunk>::as_TreeChunk(chunk)->list()->verify_stats(); 1.63 } 1.64 #endif // PRODUCT 1.65 } 1.66 @@ -1862,11 +1864,11 @@ 1.67 the excess is >= MIN_CHUNK. */ 1.68 size_t start = align_object_size(numWords + MinChunkSize); 1.69 if (start < IndexSetSize) { 1.70 - FreeList* it = _indexedFreeList; 1.71 + FreeList<FreeChunk>* it = _indexedFreeList; 1.72 size_t hint = _indexedFreeList[start].hint(); 1.73 while (hint < IndexSetSize) { 1.74 assert(hint % MinObjAlignment == 0, "hint should be aligned"); 1.75 - FreeList *fl = &_indexedFreeList[hint]; 1.76 + FreeList<FreeChunk> *fl = &_indexedFreeList[hint]; 1.77 if (fl->surplus() > 0 && fl->head() != NULL) { 1.78 // Found a list with surplus, reset original hint 1.79 // and split out a free chunk which is returned. 1.80 @@ -1885,7 +1887,7 @@ 1.81 } 1.82 1.83 /* Requires fl->size >= numWords + MinChunkSize */ 1.84 -FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList* fl, 1.85 +FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList<FreeChunk>* fl, 1.86 size_t numWords) { 1.87 FreeChunk *curr = fl->head(); 1.88 size_t oldNumWords = curr->size(); 1.89 @@ -2167,7 +2169,7 @@ 1.90 assert_locked(); 1.91 size_t i; 1.92 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 1.93 - FreeList* fl = &_indexedFreeList[i]; 1.94 + FreeList<FreeChunk>* fl = &_indexedFreeList[i]; 1.95 if (PrintFLSStatistics > 1) { 1.96 gclog_or_tty->print("size[%d] : ", i); 1.97 } 1.98 @@ -2186,7 +2188,7 @@ 1.99 assert_locked(); 1.100 size_t i; 1.101 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 1.102 - FreeList *fl = &_indexedFreeList[i]; 1.103 + FreeList<FreeChunk> *fl = &_indexedFreeList[i]; 1.104 fl->set_surplus(fl->count() - 1.105 (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent)); 1.106 } 1.107 @@ -2197,7 +2199,7 @@ 1.108 size_t i; 1.109 size_t h = IndexSetSize; 1.110 for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) { 1.111 - FreeList *fl = &_indexedFreeList[i]; 1.112 + FreeList<FreeChunk> *fl = &_indexedFreeList[i]; 1.113 fl->set_hint(h); 1.114 if (fl->surplus() > 0) { 1.115 h = i; 1.116 @@ -2209,7 +2211,7 @@ 1.117 assert_locked(); 1.118 size_t i; 1.119 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 1.120 - FreeList *fl = &_indexedFreeList[i]; 1.121 + FreeList<FreeChunk> *fl = &_indexedFreeList[i]; 1.122 fl->set_prevSweep(fl->count()); 1.123 fl->set_coalBirths(0); 1.124 fl->set_coalDeaths(0); 1.125 @@ -2236,7 +2238,7 @@ 1.126 1.127 bool CompactibleFreeListSpace::coalOverPopulated(size_t size) { 1.128 if (size < SmallForDictionary) { 1.129 - FreeList *fl = &_indexedFreeList[size]; 1.130 + FreeList<FreeChunk> *fl = &_indexedFreeList[size]; 1.131 return (fl->coalDesired() < 0) || 1.132 ((int)fl->count() > fl->coalDesired()); 1.133 } else { 1.134 @@ -2246,14 +2248,14 @@ 1.135 1.136 void CompactibleFreeListSpace::smallCoalBirth(size_t size) { 1.137 assert(size < SmallForDictionary, "Size too large for indexed list"); 1.138 - FreeList *fl = &_indexedFreeList[size]; 1.139 + FreeList<FreeChunk> *fl = &_indexedFreeList[size]; 1.140 fl->increment_coalBirths(); 1.141 fl->increment_surplus(); 1.142 } 1.143 1.144 void CompactibleFreeListSpace::smallCoalDeath(size_t size) { 1.145 assert(size < SmallForDictionary, "Size too large for indexed list"); 1.146 - FreeList *fl = &_indexedFreeList[size]; 1.147 + FreeList<FreeChunk> *fl = &_indexedFreeList[size]; 1.148 fl->increment_coalDeaths(); 1.149 fl->decrement_surplus(); 1.150 } 1.151 @@ -2280,14 +2282,14 @@ 1.152 1.153 void CompactibleFreeListSpace::smallSplitBirth(size_t size) { 1.154 assert(size < SmallForDictionary, "Size too large for indexed list"); 1.155 - FreeList *fl = &_indexedFreeList[size]; 1.156 + FreeList<FreeChunk> *fl = &_indexedFreeList[size]; 1.157 fl->increment_splitBirths(); 1.158 fl->increment_surplus(); 1.159 } 1.160 1.161 void CompactibleFreeListSpace::smallSplitDeath(size_t size) { 1.162 assert(size < SmallForDictionary, "Size too large for indexed list"); 1.163 - FreeList *fl = &_indexedFreeList[size]; 1.164 + FreeList<FreeChunk> *fl = &_indexedFreeList[size]; 1.165 fl->increment_splitDeaths(); 1.166 fl->decrement_surplus(); 1.167 } 1.168 @@ -2530,7 +2532,7 @@ 1.169 assert(_dictionary->minSize() <= IndexSetSize, 1.170 "Some sizes can't be allocated without recourse to" 1.171 " linear allocation buffers"); 1.172 - assert(MIN_TREE_CHUNK_SIZE*HeapWordSize == sizeof(TreeChunk), 1.173 + assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>), 1.174 "else MIN_TREE_CHUNK_SIZE is wrong"); 1.175 assert((IndexSetStride == 2 && IndexSetStart == 4) || // 32-bit 1.176 (IndexSetStride == 1 && IndexSetStart == 3), "just checking"); // 64-bit 1.177 @@ -2543,15 +2545,15 @@ 1.178 1.179 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { 1.180 assert_lock_strong(&_freelistLock); 1.181 - FreeList total; 1.182 + FreeList<FreeChunk> total; 1.183 gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); 1.184 - FreeList::print_labels_on(gclog_or_tty, "size"); 1.185 + FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); 1.186 size_t totalFree = 0; 1.187 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 1.188 - const FreeList *fl = &_indexedFreeList[i]; 1.189 + const FreeList<FreeChunk> *fl = &_indexedFreeList[i]; 1.190 totalFree += fl->count() * fl->size(); 1.191 if (i % (40*IndexSetStride) == 0) { 1.192 - FreeList::print_labels_on(gclog_or_tty, "size"); 1.193 + FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); 1.194 } 1.195 fl->print_on(gclog_or_tty); 1.196 total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() ); 1.197 @@ -2634,7 +2636,7 @@ 1.198 res = _cfls->getChunkFromDictionaryExact(word_sz); 1.199 if (res == NULL) return NULL; 1.200 } else { 1.201 - FreeList* fl = &_indexedFreeList[word_sz]; 1.202 + FreeList<FreeChunk>* fl = &_indexedFreeList[word_sz]; 1.203 if (fl->count() == 0) { 1.204 // Attempt to refill this local free list. 1.205 get_from_global_pool(word_sz, fl); 1.206 @@ -2654,7 +2656,7 @@ 1.207 1.208 // Get a chunk of blocks of the right size and update related 1.209 // book-keeping stats 1.210 -void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList* fl) { 1.211 +void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList<FreeChunk>* fl) { 1.212 // Get the #blocks we want to claim 1.213 size_t n_blks = (size_t)_blocks_to_claim[word_sz].average(); 1.214 assert(n_blks > 0, "Error"); 1.215 @@ -2736,7 +2738,7 @@ 1.216 if (num_retire > 0) { 1.217 _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]); 1.218 // Reset this list. 1.219 - _indexedFreeList[i] = FreeList(); 1.220 + _indexedFreeList[i] = FreeList<FreeChunk>(); 1.221 _indexedFreeList[i].set_size(i); 1.222 } 1.223 } 1.224 @@ -2750,7 +2752,7 @@ 1.225 } 1.226 } 1.227 1.228 -void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) { 1.229 +void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList<FreeChunk>* fl) { 1.230 assert(fl->count() == 0, "Precondition."); 1.231 assert(word_sz < CompactibleFreeListSpace::IndexSetSize, 1.232 "Precondition"); 1.233 @@ -2766,12 +2768,12 @@ 1.234 (cur_sz < CompactibleFreeListSpace::IndexSetSize) && 1.235 (CMSSplitIndexedFreeListBlocks || k <= 1); 1.236 k++, cur_sz = k * word_sz) { 1.237 - FreeList fl_for_cur_sz; // Empty. 1.238 + FreeList<FreeChunk> fl_for_cur_sz; // Empty. 1.239 fl_for_cur_sz.set_size(cur_sz); 1.240 { 1.241 MutexLockerEx x(_indexedFreeListParLocks[cur_sz], 1.242 Mutex::_no_safepoint_check_flag); 1.243 - FreeList* gfl = &_indexedFreeList[cur_sz]; 1.244 + FreeList<FreeChunk>* gfl = &_indexedFreeList[cur_sz]; 1.245 if (gfl->count() != 0) { 1.246 // nn is the number of chunks of size cur_sz that 1.247 // we'd need to split k-ways each, in order to create 1.248 @@ -2848,7 +2850,7 @@ 1.249 while (n > 0) { 1.250 fc = dictionary()->getChunk(MAX2(n * word_sz, 1.251 _dictionary->minSize()), 1.252 - FreeBlockDictionary::atLeast); 1.253 + FreeBlockDictionary<FreeChunk>::atLeast); 1.254 if (fc != NULL) { 1.255 _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk 1.256 dictionary()->dictCensusUpdate(fc->size(),