Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @ 6885:685df3c6f84b
7045397: NPG: Add freelists to class loader arenas.
Reviewed-by: coleenp, stefank, jprovino, ohair
author | jmasa |
---|---|
date | Tue, 18 Sep 2012 23:35:42 -0700 |
parents | da91efe96a93 |
children | b735136e0d82 203f64878aab |
comparison
equal
deleted
inserted
replaced
6877:d0e7716b179e | 6885:685df3c6f84b |
---|---|
89 _marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord * | 89 _marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord * |
90 CMSConcMarkMultiple), | 90 CMSConcMarkMultiple), |
91 _collector(NULL) | 91 _collector(NULL) |
92 { | 92 { |
93 assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize, | 93 assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize, |
94 "FreeChunk is larger than expected"); | 94 "FreeChunk is larger than expected"); |
95 _bt.set_space(this); | 95 _bt.set_space(this); |
96 initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); | 96 initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); |
97 // We have all of "mr", all of which we place in the dictionary | 97 // We have all of "mr", all of which we place in the dictionary |
98 // as one big chunk. We'll need to decide here which of several | 98 // as one big chunk. We'll need to decide here which of several |
99 // possible alternative dictionary implementations to use. For | 99 // possible alternative dictionary implementations to use. For |
100 // now the choice is easy, since we have only one working | 100 // now the choice is easy, since we have only one working |
101 // implementation, namely, the simple binary tree (splaying | 101 // implementation, namely, the simple binary tree (splaying |
102 // temporarily disabled). | 102 // temporarily disabled). |
103 switch (dictionaryChoice) { | 103 switch (dictionaryChoice) { |
104 case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree: | |
105 _dictionary = new BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>(mr); | |
106 break; | |
104 case FreeBlockDictionary<FreeChunk>::dictionarySplayTree: | 107 case FreeBlockDictionary<FreeChunk>::dictionarySplayTree: |
105 case FreeBlockDictionary<FreeChunk>::dictionarySkipList: | 108 case FreeBlockDictionary<FreeChunk>::dictionarySkipList: |
106 default: | 109 default: |
107 warning("dictionaryChoice: selected option not understood; using" | 110 warning("dictionaryChoice: selected option not understood; using" |
108 " default BinaryTreeDictionary implementation instead."); | 111 " default BinaryTreeDictionary implementation instead."); |
109 case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree: | |
110 _dictionary = new BinaryTreeDictionary<FreeChunk>(mr, use_adaptive_freelists); | |
111 break; | |
112 } | 112 } |
113 assert(_dictionary != NULL, "CMS dictionary initialization"); | 113 assert(_dictionary != NULL, "CMS dictionary initialization"); |
114 // The indexed free lists are initially all empty and are lazily | 114 // The indexed free lists are initially all empty and are lazily |
115 // filled in on demand. Initialize the array elements to NULL. | 115 // filled in on demand. Initialize the array elements to NULL. |
116 initializeIndexedFreeListArray(); | 116 initializeIndexedFreeListArray(); |
451 void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st) | 451 void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st) |
452 const { | 452 const { |
453 reportIndexedFreeListStatistics(); | 453 reportIndexedFreeListStatistics(); |
454 gclog_or_tty->print_cr("Layout of Indexed Freelists"); | 454 gclog_or_tty->print_cr("Layout of Indexed Freelists"); |
455 gclog_or_tty->print_cr("---------------------------"); | 455 gclog_or_tty->print_cr("---------------------------"); |
456 FreeList<FreeChunk>::print_labels_on(st, "size"); | 456 AdaptiveFreeList<FreeChunk>::print_labels_on(st, "size"); |
457 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { | 457 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { |
458 _indexedFreeList[i].print_on(gclog_or_tty); | 458 _indexedFreeList[i].print_on(gclog_or_tty); |
459 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; | 459 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; |
460 fc = fc->next()) { | 460 fc = fc->next()) { |
461 gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", | 461 gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", |
1317 | 1317 |
1318 size_t i; | 1318 size_t i; |
1319 size_t currSize = numWords + MinChunkSize; | 1319 size_t currSize = numWords + MinChunkSize; |
1320 assert(currSize % MinObjAlignment == 0, "currSize should be aligned"); | 1320 assert(currSize % MinObjAlignment == 0, "currSize should be aligned"); |
1321 for (i = currSize; i < IndexSetSize; i += IndexSetStride) { | 1321 for (i = currSize; i < IndexSetSize; i += IndexSetStride) { |
1322 FreeList<FreeChunk>* fl = &_indexedFreeList[i]; | 1322 AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[i]; |
1323 if (fl->head()) { | 1323 if (fl->head()) { |
1324 ret = getFromListGreater(fl, numWords); | 1324 ret = getFromListGreater(fl, numWords); |
1325 assert(ret == NULL || ret->is_free(), "Should be returning a free chunk"); | 1325 assert(ret == NULL || ret->is_free(), "Should be returning a free chunk"); |
1326 return ret; | 1326 return ret; |
1327 } | 1327 } |
1700 // adjust _unallocated_block downward, as necessary | 1700 // adjust _unallocated_block downward, as necessary |
1701 _bt.freed((HeapWord*)chunk, size); | 1701 _bt.freed((HeapWord*)chunk, size); |
1702 _dictionary->return_chunk(chunk); | 1702 _dictionary->return_chunk(chunk); |
1703 #ifndef PRODUCT | 1703 #ifndef PRODUCT |
1704 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) { | 1704 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) { |
1705 TreeChunk<FreeChunk>::as_TreeChunk(chunk)->list()->verify_stats(); | 1705 TreeChunk<FreeChunk, AdaptiveFreeList>* tc = TreeChunk<FreeChunk, AdaptiveFreeList>::as_TreeChunk(chunk); |
1706 TreeList<FreeChunk, AdaptiveFreeList>* tl = tc->list(); | |
1707 tl->verify_stats(); | |
1706 } | 1708 } |
1707 #endif // PRODUCT | 1709 #endif // PRODUCT |
1708 } | 1710 } |
1709 | 1711 |
1710 void | 1712 void |
1743 } | 1745 } |
1744 FreeChunk* ec; | 1746 FreeChunk* ec; |
1745 { | 1747 { |
1746 MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag); | 1748 MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag); |
1747 ec = dictionary()->find_largest_dict(); // get largest block | 1749 ec = dictionary()->find_largest_dict(); // get largest block |
1748 if (ec != NULL && ec->end() == chunk) { | 1750 if (ec != NULL && ec->end() == (uintptr_t*) chunk) { |
1749 // It's a coterminal block - we can coalesce. | 1751 // It's a coterminal block - we can coalesce. |
1750 size_t old_size = ec->size(); | 1752 size_t old_size = ec->size(); |
1751 coalDeath(old_size); | 1753 coalDeath(old_size); |
1752 removeChunkFromDictionary(ec); | 1754 removeChunkFromDictionary(ec); |
1753 size += old_size; | 1755 size += old_size; |
1848 /* A hint is the next larger size that has a surplus. | 1850 /* A hint is the next larger size that has a surplus. |
1849 Start search at a size large enough to guarantee that | 1851 Start search at a size large enough to guarantee that |
1850 the excess is >= MIN_CHUNK. */ | 1852 the excess is >= MIN_CHUNK. */ |
1851 size_t start = align_object_size(numWords + MinChunkSize); | 1853 size_t start = align_object_size(numWords + MinChunkSize); |
1852 if (start < IndexSetSize) { | 1854 if (start < IndexSetSize) { |
1853 FreeList<FreeChunk>* it = _indexedFreeList; | 1855 AdaptiveFreeList<FreeChunk>* it = _indexedFreeList; |
1854 size_t hint = _indexedFreeList[start].hint(); | 1856 size_t hint = _indexedFreeList[start].hint(); |
1855 while (hint < IndexSetSize) { | 1857 while (hint < IndexSetSize) { |
1856 assert(hint % MinObjAlignment == 0, "hint should be aligned"); | 1858 assert(hint % MinObjAlignment == 0, "hint should be aligned"); |
1857 FreeList<FreeChunk> *fl = &_indexedFreeList[hint]; | 1859 AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[hint]; |
1858 if (fl->surplus() > 0 && fl->head() != NULL) { | 1860 if (fl->surplus() > 0 && fl->head() != NULL) { |
1859 // Found a list with surplus, reset original hint | 1861 // Found a list with surplus, reset original hint |
1860 // and split out a free chunk which is returned. | 1862 // and split out a free chunk which is returned. |
1861 _indexedFreeList[start].set_hint(hint); | 1863 _indexedFreeList[start].set_hint(hint); |
1862 FreeChunk* res = getFromListGreater(fl, numWords); | 1864 FreeChunk* res = getFromListGreater(fl, numWords); |
1871 } | 1873 } |
1872 return NULL; | 1874 return NULL; |
1873 } | 1875 } |
1874 | 1876 |
1875 /* Requires fl->size >= numWords + MinChunkSize */ | 1877 /* Requires fl->size >= numWords + MinChunkSize */ |
1876 FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList<FreeChunk>* fl, | 1878 FreeChunk* CompactibleFreeListSpace::getFromListGreater(AdaptiveFreeList<FreeChunk>* fl, |
1877 size_t numWords) { | 1879 size_t numWords) { |
1878 FreeChunk *curr = fl->head(); | 1880 FreeChunk *curr = fl->head(); |
1879 size_t oldNumWords = curr->size(); | 1881 size_t oldNumWords = curr->size(); |
1880 assert(numWords >= MinChunkSize, "Word size is too small"); | 1882 assert(numWords >= MinChunkSize, "Word size is too small"); |
1881 assert(curr != NULL, "List is empty"); | 1883 assert(curr != NULL, "List is empty"); |
2153 float inter_sweep_estimate, | 2155 float inter_sweep_estimate, |
2154 float intra_sweep_estimate) { | 2156 float intra_sweep_estimate) { |
2155 assert_locked(); | 2157 assert_locked(); |
2156 size_t i; | 2158 size_t i; |
2157 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { | 2159 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { |
2158 FreeList<FreeChunk>* fl = &_indexedFreeList[i]; | 2160 AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[i]; |
2159 if (PrintFLSStatistics > 1) { | 2161 if (PrintFLSStatistics > 1) { |
2160 gclog_or_tty->print("size[%d] : ", i); | 2162 gclog_or_tty->print("size[%d] : ", i); |
2161 } | 2163 } |
2162 fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); | 2164 fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); |
2163 fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent)); | 2165 fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent)); |
2172 | 2174 |
2173 void CompactibleFreeListSpace::setFLSurplus() { | 2175 void CompactibleFreeListSpace::setFLSurplus() { |
2174 assert_locked(); | 2176 assert_locked(); |
2175 size_t i; | 2177 size_t i; |
2176 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { | 2178 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { |
2177 FreeList<FreeChunk> *fl = &_indexedFreeList[i]; | 2179 AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i]; |
2178 fl->set_surplus(fl->count() - | 2180 fl->set_surplus(fl->count() - |
2179 (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent)); | 2181 (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent)); |
2180 } | 2182 } |
2181 } | 2183 } |
2182 | 2184 |
2183 void CompactibleFreeListSpace::setFLHints() { | 2185 void CompactibleFreeListSpace::setFLHints() { |
2184 assert_locked(); | 2186 assert_locked(); |
2185 size_t i; | 2187 size_t i; |
2186 size_t h = IndexSetSize; | 2188 size_t h = IndexSetSize; |
2187 for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) { | 2189 for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) { |
2188 FreeList<FreeChunk> *fl = &_indexedFreeList[i]; | 2190 AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i]; |
2189 fl->set_hint(h); | 2191 fl->set_hint(h); |
2190 if (fl->surplus() > 0) { | 2192 if (fl->surplus() > 0) { |
2191 h = i; | 2193 h = i; |
2192 } | 2194 } |
2193 } | 2195 } |
2195 | 2197 |
2196 void CompactibleFreeListSpace::clearFLCensus() { | 2198 void CompactibleFreeListSpace::clearFLCensus() { |
2197 assert_locked(); | 2199 assert_locked(); |
2198 size_t i; | 2200 size_t i; |
2199 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { | 2201 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { |
2200 FreeList<FreeChunk> *fl = &_indexedFreeList[i]; | 2202 AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i]; |
2201 fl->set_prev_sweep(fl->count()); | 2203 fl->set_prev_sweep(fl->count()); |
2202 fl->set_coal_births(0); | 2204 fl->set_coal_births(0); |
2203 fl->set_coal_deaths(0); | 2205 fl->set_coal_deaths(0); |
2204 fl->set_split_births(0); | 2206 fl->set_split_births(0); |
2205 fl->set_split_deaths(0); | 2207 fl->set_split_deaths(0); |
2222 _dictionary->end_sweep_dict_census(CMSLargeSplitSurplusPercent); | 2224 _dictionary->end_sweep_dict_census(CMSLargeSplitSurplusPercent); |
2223 } | 2225 } |
2224 | 2226 |
2225 bool CompactibleFreeListSpace::coalOverPopulated(size_t size) { | 2227 bool CompactibleFreeListSpace::coalOverPopulated(size_t size) { |
2226 if (size < SmallForDictionary) { | 2228 if (size < SmallForDictionary) { |
2227 FreeList<FreeChunk> *fl = &_indexedFreeList[size]; | 2229 AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size]; |
2228 return (fl->coal_desired() < 0) || | 2230 return (fl->coal_desired() < 0) || |
2229 ((int)fl->count() > fl->coal_desired()); | 2231 ((int)fl->count() > fl->coal_desired()); |
2230 } else { | 2232 } else { |
2231 return dictionary()->coal_dict_over_populated(size); | 2233 return dictionary()->coal_dict_over_populated(size); |
2232 } | 2234 } |
2233 } | 2235 } |
2234 | 2236 |
2235 void CompactibleFreeListSpace::smallCoalBirth(size_t size) { | 2237 void CompactibleFreeListSpace::smallCoalBirth(size_t size) { |
2236 assert(size < SmallForDictionary, "Size too large for indexed list"); | 2238 assert(size < SmallForDictionary, "Size too large for indexed list"); |
2237 FreeList<FreeChunk> *fl = &_indexedFreeList[size]; | 2239 AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size]; |
2238 fl->increment_coal_births(); | 2240 fl->increment_coal_births(); |
2239 fl->increment_surplus(); | 2241 fl->increment_surplus(); |
2240 } | 2242 } |
2241 | 2243 |
2242 void CompactibleFreeListSpace::smallCoalDeath(size_t size) { | 2244 void CompactibleFreeListSpace::smallCoalDeath(size_t size) { |
2243 assert(size < SmallForDictionary, "Size too large for indexed list"); | 2245 assert(size < SmallForDictionary, "Size too large for indexed list"); |
2244 FreeList<FreeChunk> *fl = &_indexedFreeList[size]; | 2246 AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size]; |
2245 fl->increment_coal_deaths(); | 2247 fl->increment_coal_deaths(); |
2246 fl->decrement_surplus(); | 2248 fl->decrement_surplus(); |
2247 } | 2249 } |
2248 | 2250 |
2249 void CompactibleFreeListSpace::coalBirth(size_t size) { | 2251 void CompactibleFreeListSpace::coalBirth(size_t size) { |
2250 if (size < SmallForDictionary) { | 2252 if (size < SmallForDictionary) { |
2251 smallCoalBirth(size); | 2253 smallCoalBirth(size); |
2252 } else { | 2254 } else { |
2253 dictionary()->dict_census_udpate(size, | 2255 dictionary()->dict_census_update(size, |
2254 false /* split */, | 2256 false /* split */, |
2255 true /* birth */); | 2257 true /* birth */); |
2256 } | 2258 } |
2257 } | 2259 } |
2258 | 2260 |
2259 void CompactibleFreeListSpace::coalDeath(size_t size) { | 2261 void CompactibleFreeListSpace::coalDeath(size_t size) { |
2260 if(size < SmallForDictionary) { | 2262 if(size < SmallForDictionary) { |
2261 smallCoalDeath(size); | 2263 smallCoalDeath(size); |
2262 } else { | 2264 } else { |
2263 dictionary()->dict_census_udpate(size, | 2265 dictionary()->dict_census_update(size, |
2264 false /* split */, | 2266 false /* split */, |
2265 false /* birth */); | 2267 false /* birth */); |
2266 } | 2268 } |
2267 } | 2269 } |
2268 | 2270 |
2269 void CompactibleFreeListSpace::smallSplitBirth(size_t size) { | 2271 void CompactibleFreeListSpace::smallSplitBirth(size_t size) { |
2270 assert(size < SmallForDictionary, "Size too large for indexed list"); | 2272 assert(size < SmallForDictionary, "Size too large for indexed list"); |
2271 FreeList<FreeChunk> *fl = &_indexedFreeList[size]; | 2273 AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size]; |
2272 fl->increment_split_births(); | 2274 fl->increment_split_births(); |
2273 fl->increment_surplus(); | 2275 fl->increment_surplus(); |
2274 } | 2276 } |
2275 | 2277 |
2276 void CompactibleFreeListSpace::smallSplitDeath(size_t size) { | 2278 void CompactibleFreeListSpace::smallSplitDeath(size_t size) { |
2277 assert(size < SmallForDictionary, "Size too large for indexed list"); | 2279 assert(size < SmallForDictionary, "Size too large for indexed list"); |
2278 FreeList<FreeChunk> *fl = &_indexedFreeList[size]; | 2280 AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size]; |
2279 fl->increment_split_deaths(); | 2281 fl->increment_split_deaths(); |
2280 fl->decrement_surplus(); | 2282 fl->decrement_surplus(); |
2281 } | 2283 } |
2282 | 2284 |
2283 void CompactibleFreeListSpace::split_birth(size_t size) { | 2285 void CompactibleFreeListSpace::split_birth(size_t size) { |
2284 if (size < SmallForDictionary) { | 2286 if (size < SmallForDictionary) { |
2285 smallSplitBirth(size); | 2287 smallSplitBirth(size); |
2286 } else { | 2288 } else { |
2287 dictionary()->dict_census_udpate(size, | 2289 dictionary()->dict_census_update(size, |
2288 true /* split */, | 2290 true /* split */, |
2289 true /* birth */); | 2291 true /* birth */); |
2290 } | 2292 } |
2291 } | 2293 } |
2292 | 2294 |
2293 void CompactibleFreeListSpace::splitDeath(size_t size) { | 2295 void CompactibleFreeListSpace::splitDeath(size_t size) { |
2294 if (size < SmallForDictionary) { | 2296 if (size < SmallForDictionary) { |
2295 smallSplitDeath(size); | 2297 smallSplitDeath(size); |
2296 } else { | 2298 } else { |
2297 dictionary()->dict_census_udpate(size, | 2299 dictionary()->dict_census_update(size, |
2298 true /* split */, | 2300 true /* split */, |
2299 false /* birth */); | 2301 false /* birth */); |
2300 } | 2302 } |
2301 } | 2303 } |
2302 | 2304 |
2515 guarantee(n == num, "Incorrect count"); | 2517 guarantee(n == num, "Incorrect count"); |
2516 } | 2518 } |
2517 | 2519 |
2518 #ifndef PRODUCT | 2520 #ifndef PRODUCT |
2519 void CompactibleFreeListSpace::check_free_list_consistency() const { | 2521 void CompactibleFreeListSpace::check_free_list_consistency() const { |
2520 assert(_dictionary->min_size() <= IndexSetSize, | 2522 assert((TreeChunk<FreeChunk, AdaptiveFreeList>::min_size() <= IndexSetSize), |
2521 "Some sizes can't be allocated without recourse to" | 2523 "Some sizes can't be allocated without recourse to" |
2522 " linear allocation buffers"); | 2524 " linear allocation buffers"); |
2523 assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>), | 2525 assert((TreeChunk<FreeChunk, AdaptiveFreeList>::min_size()*HeapWordSize == sizeof(TreeChunk<FreeChunk, AdaptiveFreeList>)), |
2524 "else MIN_TREE_CHUNK_SIZE is wrong"); | 2526 "else MIN_TREE_CHUNK_SIZE is wrong"); |
2525 assert(IndexSetStart != 0, "IndexSetStart not initialized"); | 2527 assert(IndexSetStart != 0, "IndexSetStart not initialized"); |
2526 assert(IndexSetStride != 0, "IndexSetStride not initialized"); | 2528 assert(IndexSetStride != 0, "IndexSetStride not initialized"); |
2527 } | 2529 } |
2528 #endif | 2530 #endif |
2529 | 2531 |
2530 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { | 2532 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { |
2531 assert_lock_strong(&_freelistLock); | 2533 assert_lock_strong(&_freelistLock); |
2532 FreeList<FreeChunk> total; | 2534 AdaptiveFreeList<FreeChunk> total; |
2533 gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); | 2535 gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); |
2534 FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); | 2536 AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); |
2535 size_t total_free = 0; | 2537 size_t total_free = 0; |
2536 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { | 2538 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { |
2537 const FreeList<FreeChunk> *fl = &_indexedFreeList[i]; | 2539 const AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i]; |
2538 total_free += fl->count() * fl->size(); | 2540 total_free += fl->count() * fl->size(); |
2539 if (i % (40*IndexSetStride) == 0) { | 2541 if (i % (40*IndexSetStride) == 0) { |
2540 FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); | 2542 AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size"); |
2541 } | 2543 } |
2542 fl->print_on(gclog_or_tty); | 2544 fl->print_on(gclog_or_tty); |
2543 total.set_bfr_surp( total.bfr_surp() + fl->bfr_surp() ); | 2545 total.set_bfr_surp( total.bfr_surp() + fl->bfr_surp() ); |
2544 total.set_surplus( total.surplus() + fl->surplus() ); | 2546 total.set_surplus( total.surplus() + fl->surplus() ); |
2545 total.set_desired( total.desired() + fl->desired() ); | 2547 total.set_desired( total.desired() + fl->desired() ); |
2618 MutexLockerEx x(_cfls->parDictionaryAllocLock(), | 2620 MutexLockerEx x(_cfls->parDictionaryAllocLock(), |
2619 Mutex::_no_safepoint_check_flag); | 2621 Mutex::_no_safepoint_check_flag); |
2620 res = _cfls->getChunkFromDictionaryExact(word_sz); | 2622 res = _cfls->getChunkFromDictionaryExact(word_sz); |
2621 if (res == NULL) return NULL; | 2623 if (res == NULL) return NULL; |
2622 } else { | 2624 } else { |
2623 FreeList<FreeChunk>* fl = &_indexedFreeList[word_sz]; | 2625 AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[word_sz]; |
2624 if (fl->count() == 0) { | 2626 if (fl->count() == 0) { |
2625 // Attempt to refill this local free list. | 2627 // Attempt to refill this local free list. |
2626 get_from_global_pool(word_sz, fl); | 2628 get_from_global_pool(word_sz, fl); |
2627 // If it didn't work, give up. | 2629 // If it didn't work, give up. |
2628 if (fl->count() == 0) return NULL; | 2630 if (fl->count() == 0) return NULL; |
2638 return (HeapWord*)res; | 2640 return (HeapWord*)res; |
2639 } | 2641 } |
2640 | 2642 |
2641 // Get a chunk of blocks of the right size and update related | 2643 // Get a chunk of blocks of the right size and update related |
2642 // book-keeping stats | 2644 // book-keeping stats |
2643 void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList<FreeChunk>* fl) { | 2645 void CFLS_LAB::get_from_global_pool(size_t word_sz, AdaptiveFreeList<FreeChunk>* fl) { |
2644 // Get the #blocks we want to claim | 2646 // Get the #blocks we want to claim |
2645 size_t n_blks = (size_t)_blocks_to_claim[word_sz].average(); | 2647 size_t n_blks = (size_t)_blocks_to_claim[word_sz].average(); |
2646 assert(n_blks > 0, "Error"); | 2648 assert(n_blks > 0, "Error"); |
2647 assert(ResizePLAB || n_blks == OldPLABSize, "Error"); | 2649 assert(ResizePLAB || n_blks == OldPLABSize, "Error"); |
2648 // In some cases, when the application has a phase change, | 2650 // In some cases, when the application has a phase change, |
2720 _global_num_workers[i]++; | 2722 _global_num_workers[i]++; |
2721 assert(_global_num_workers[i] <= ParallelGCThreads, "Too big"); | 2723 assert(_global_num_workers[i] <= ParallelGCThreads, "Too big"); |
2722 if (num_retire > 0) { | 2724 if (num_retire > 0) { |
2723 _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]); | 2725 _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]); |
2724 // Reset this list. | 2726 // Reset this list. |
2725 _indexedFreeList[i] = FreeList<FreeChunk>(); | 2727 _indexedFreeList[i] = AdaptiveFreeList<FreeChunk>(); |
2726 _indexedFreeList[i].set_size(i); | 2728 _indexedFreeList[i].set_size(i); |
2727 } | 2729 } |
2728 } | 2730 } |
2729 if (PrintOldPLAB) { | 2731 if (PrintOldPLAB) { |
2730 gclog_or_tty->print_cr("%d[%d]: %d/%d/%d", | 2732 gclog_or_tty->print_cr("%d[%d]: %d/%d/%d", |
2734 _num_blocks[i] = 0; | 2736 _num_blocks[i] = 0; |
2735 } | 2737 } |
2736 } | 2738 } |
2737 } | 2739 } |
2738 | 2740 |
2739 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList<FreeChunk>* fl) { | 2741 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) { |
2740 assert(fl->count() == 0, "Precondition."); | 2742 assert(fl->count() == 0, "Precondition."); |
2741 assert(word_sz < CompactibleFreeListSpace::IndexSetSize, | 2743 assert(word_sz < CompactibleFreeListSpace::IndexSetSize, |
2742 "Precondition"); | 2744 "Precondition"); |
2743 | 2745 |
2744 // We'll try all multiples of word_sz in the indexed set, starting with | 2746 // We'll try all multiples of word_sz in the indexed set, starting with |
2750 size_t cur_sz; | 2752 size_t cur_sz; |
2751 for (k = 1, cur_sz = k * word_sz, found = false; | 2753 for (k = 1, cur_sz = k * word_sz, found = false; |
2752 (cur_sz < CompactibleFreeListSpace::IndexSetSize) && | 2754 (cur_sz < CompactibleFreeListSpace::IndexSetSize) && |
2753 (CMSSplitIndexedFreeListBlocks || k <= 1); | 2755 (CMSSplitIndexedFreeListBlocks || k <= 1); |
2754 k++, cur_sz = k * word_sz) { | 2756 k++, cur_sz = k * word_sz) { |
2755 FreeList<FreeChunk> fl_for_cur_sz; // Empty. | 2757 AdaptiveFreeList<FreeChunk> fl_for_cur_sz; // Empty. |
2756 fl_for_cur_sz.set_size(cur_sz); | 2758 fl_for_cur_sz.set_size(cur_sz); |
2757 { | 2759 { |
2758 MutexLockerEx x(_indexedFreeListParLocks[cur_sz], | 2760 MutexLockerEx x(_indexedFreeListParLocks[cur_sz], |
2759 Mutex::_no_safepoint_check_flag); | 2761 Mutex::_no_safepoint_check_flag); |
2760 FreeList<FreeChunk>* gfl = &_indexedFreeList[cur_sz]; | 2762 AdaptiveFreeList<FreeChunk>* gfl = &_indexedFreeList[cur_sz]; |
2761 if (gfl->count() != 0) { | 2763 if (gfl->count() != 0) { |
2762 // nn is the number of chunks of size cur_sz that | 2764 // nn is the number of chunks of size cur_sz that |
2763 // we'd need to split k-ways each, in order to create | 2765 // we'd need to split k-ways each, in order to create |
2764 // "n" chunks of size word_sz each. | 2766 // "n" chunks of size word_sz each. |
2765 const size_t nn = MAX2(n/k, (size_t)1); | 2767 const size_t nn = MAX2(n/k, (size_t)1); |
2830 size_t rem; | 2832 size_t rem; |
2831 { | 2833 { |
2832 MutexLockerEx x(parDictionaryAllocLock(), | 2834 MutexLockerEx x(parDictionaryAllocLock(), |
2833 Mutex::_no_safepoint_check_flag); | 2835 Mutex::_no_safepoint_check_flag); |
2834 while (n > 0) { | 2836 while (n > 0) { |
2835 fc = dictionary()->get_chunk(MAX2(n * word_sz, | 2837 fc = dictionary()->get_chunk(MAX2(n * word_sz, _dictionary->min_size()), |
2836 _dictionary->min_size()), | |
2837 FreeBlockDictionary<FreeChunk>::atLeast); | 2838 FreeBlockDictionary<FreeChunk>::atLeast); |
2838 if (fc != NULL) { | 2839 if (fc != NULL) { |
2839 _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk | 2840 _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk |
2840 dictionary()->dict_census_udpate(fc->size(), | 2841 dictionary()->dict_census_update(fc->size(), |
2841 true /*split*/, | 2842 true /*split*/, |
2842 false /*birth*/); | 2843 false /*birth*/); |
2843 break; | 2844 break; |
2844 } else { | 2845 } else { |
2845 n--; | 2846 n--; |
2888 _bt.split_block((HeapWord*)fc, fc->size(), prefix_size); | 2889 _bt.split_block((HeapWord*)fc, fc->size(), prefix_size); |
2889 assert(fc->is_free(), "Error"); | 2890 assert(fc->is_free(), "Error"); |
2890 fc->set_size(prefix_size); | 2891 fc->set_size(prefix_size); |
2891 if (rem >= IndexSetSize) { | 2892 if (rem >= IndexSetSize) { |
2892 returnChunkToDictionary(rem_fc); | 2893 returnChunkToDictionary(rem_fc); |
2893 dictionary()->dict_census_udpate(rem, true /*split*/, true /*birth*/); | 2894 dictionary()->dict_census_update(rem, true /*split*/, true /*birth*/); |
2894 rem_fc = NULL; | 2895 rem_fc = NULL; |
2895 } | 2896 } |
2896 // Otherwise, return it to the small list below. | 2897 // Otherwise, return it to the small list below. |
2897 } | 2898 } |
2898 } | 2899 } |