hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
changeset 14123 944e56f74fba
parent 13728 882756847a04
child 15088 8875e774f1a3
child 15228 e92acc84ade3
equal deleted inserted replaced
14115:f5e31fb61738 14123:944e56f74fba
    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   }