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", |
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); |
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 } |
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, |
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); |
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 } |