src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp

changeset 3730
9f059abe8cf2
parent 3711
b632e80fc9dc
child 3732
f69a5d43dc19
equal deleted inserted replaced
3720:3c91f2c9fd21 3730:9f059abe8cf2
67 } 67 }
68 68
69 // Constructor 69 // Constructor
70 CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs, 70 CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
71 MemRegion mr, bool use_adaptive_freelists, 71 MemRegion mr, bool use_adaptive_freelists,
72 FreeBlockDictionary::DictionaryChoice dictionaryChoice) : 72 FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
73 _dictionaryChoice(dictionaryChoice), 73 _dictionaryChoice(dictionaryChoice),
74 _adaptive_freelists(use_adaptive_freelists), 74 _adaptive_freelists(use_adaptive_freelists),
75 _bt(bs, mr), 75 _bt(bs, mr),
76 // free list locks are in the range of values taken by _lockRank 76 // free list locks are in the range of values taken by _lockRank
77 // This range currently is [_leaf+2, _leaf+3] 77 // This range currently is [_leaf+2, _leaf+3]
85 CMSRescanMultiple), 85 CMSRescanMultiple),
86 _marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord * 86 _marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord *
87 CMSConcMarkMultiple), 87 CMSConcMarkMultiple),
88 _collector(NULL) 88 _collector(NULL)
89 { 89 {
90 assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize,
91 "FreeChunk is larger than expected");
90 _bt.set_space(this); 92 _bt.set_space(this);
91 initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle); 93 initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
92 // We have all of "mr", all of which we place in the dictionary 94 // We have all of "mr", all of which we place in the dictionary
93 // as one big chunk. We'll need to decide here which of several 95 // as one big chunk. We'll need to decide here which of several
94 // possible alternative dictionary implementations to use. For 96 // possible alternative dictionary implementations to use. For
95 // now the choice is easy, since we have only one working 97 // now the choice is easy, since we have only one working
96 // implementation, namely, the simple binary tree (splaying 98 // implementation, namely, the simple binary tree (splaying
97 // temporarily disabled). 99 // temporarily disabled).
98 switch (dictionaryChoice) { 100 switch (dictionaryChoice) {
99 case FreeBlockDictionary::dictionarySplayTree: 101 case FreeBlockDictionary<FreeChunk>::dictionarySplayTree:
100 case FreeBlockDictionary::dictionarySkipList: 102 case FreeBlockDictionary<FreeChunk>::dictionarySkipList:
101 default: 103 default:
102 warning("dictionaryChoice: selected option not understood; using" 104 warning("dictionaryChoice: selected option not understood; using"
103 " default BinaryTreeDictionary implementation instead."); 105 " default BinaryTreeDictionary implementation instead.");
104 case FreeBlockDictionary::dictionaryBinaryTree: 106 case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree:
105 _dictionary = new BinaryTreeDictionary(mr); 107 _dictionary = new BinaryTreeDictionary<FreeChunk>(mr, use_adaptive_freelists);
106 break; 108 break;
107 } 109 }
108 assert(_dictionary != NULL, "CMS dictionary initialization"); 110 assert(_dictionary != NULL, "CMS dictionary initialization");
109 // The indexed free lists are initially all empty and are lazily 111 // The indexed free lists are initially all empty and are lazily
110 // filled in on demand. Initialize the array elements to NULL. 112 // filled in on demand. Initialize the array elements to NULL.
446 void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st) 448 void CompactibleFreeListSpace::print_indexed_free_lists(outputStream* st)
447 const { 449 const {
448 reportIndexedFreeListStatistics(); 450 reportIndexedFreeListStatistics();
449 gclog_or_tty->print_cr("Layout of Indexed Freelists"); 451 gclog_or_tty->print_cr("Layout of Indexed Freelists");
450 gclog_or_tty->print_cr("---------------------------"); 452 gclog_or_tty->print_cr("---------------------------");
451 FreeList::print_labels_on(st, "size"); 453 FreeList<FreeChunk>::print_labels_on(st, "size");
452 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 454 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
453 _indexedFreeList[i].print_on(gclog_or_tty); 455 _indexedFreeList[i].print_on(gclog_or_tty);
454 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL; 456 for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
455 fc = fc->next()) { 457 fc = fc->next()) {
456 gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s", 458 gclog_or_tty->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ") %s",
1329 1331
1330 size_t i; 1332 size_t i;
1331 size_t currSize = numWords + MinChunkSize; 1333 size_t currSize = numWords + MinChunkSize;
1332 assert(currSize % MinObjAlignment == 0, "currSize should be aligned"); 1334 assert(currSize % MinObjAlignment == 0, "currSize should be aligned");
1333 for (i = currSize; i < IndexSetSize; i += IndexSetStride) { 1335 for (i = currSize; i < IndexSetSize; i += IndexSetStride) {
1334 FreeList* fl = &_indexedFreeList[i]; 1336 FreeList<FreeChunk>* fl = &_indexedFreeList[i];
1335 if (fl->head()) { 1337 if (fl->head()) {
1336 ret = getFromListGreater(fl, numWords); 1338 ret = getFromListGreater(fl, numWords);
1337 assert(ret == NULL || ret->isFree(), "Should be returning a free chunk"); 1339 assert(ret == NULL || ret->isFree(), "Should be returning a free chunk");
1338 return ret; 1340 return ret;
1339 } 1341 }
1712 // adjust _unallocated_block downward, as necessary 1714 // adjust _unallocated_block downward, as necessary
1713 _bt.freed((HeapWord*)chunk, size); 1715 _bt.freed((HeapWord*)chunk, size);
1714 _dictionary->returnChunk(chunk); 1716 _dictionary->returnChunk(chunk);
1715 #ifndef PRODUCT 1717 #ifndef PRODUCT
1716 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) { 1718 if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
1717 TreeChunk::as_TreeChunk(chunk)->list()->verify_stats(); 1719 TreeChunk<FreeChunk>::as_TreeChunk(chunk)->list()->verify_stats();
1718 } 1720 }
1719 #endif // PRODUCT 1721 #endif // PRODUCT
1720 } 1722 }
1721 1723
1722 void 1724 void
1860 /* A hint is the next larger size that has a surplus. 1862 /* A hint is the next larger size that has a surplus.
1861 Start search at a size large enough to guarantee that 1863 Start search at a size large enough to guarantee that
1862 the excess is >= MIN_CHUNK. */ 1864 the excess is >= MIN_CHUNK. */
1863 size_t start = align_object_size(numWords + MinChunkSize); 1865 size_t start = align_object_size(numWords + MinChunkSize);
1864 if (start < IndexSetSize) { 1866 if (start < IndexSetSize) {
1865 FreeList* it = _indexedFreeList; 1867 FreeList<FreeChunk>* it = _indexedFreeList;
1866 size_t hint = _indexedFreeList[start].hint(); 1868 size_t hint = _indexedFreeList[start].hint();
1867 while (hint < IndexSetSize) { 1869 while (hint < IndexSetSize) {
1868 assert(hint % MinObjAlignment == 0, "hint should be aligned"); 1870 assert(hint % MinObjAlignment == 0, "hint should be aligned");
1869 FreeList *fl = &_indexedFreeList[hint]; 1871 FreeList<FreeChunk> *fl = &_indexedFreeList[hint];
1870 if (fl->surplus() > 0 && fl->head() != NULL) { 1872 if (fl->surplus() > 0 && fl->head() != NULL) {
1871 // Found a list with surplus, reset original hint 1873 // Found a list with surplus, reset original hint
1872 // and split out a free chunk which is returned. 1874 // and split out a free chunk which is returned.
1873 _indexedFreeList[start].set_hint(hint); 1875 _indexedFreeList[start].set_hint(hint);
1874 FreeChunk* res = getFromListGreater(fl, numWords); 1876 FreeChunk* res = getFromListGreater(fl, numWords);
1883 } 1885 }
1884 return NULL; 1886 return NULL;
1885 } 1887 }
1886 1888
1887 /* Requires fl->size >= numWords + MinChunkSize */ 1889 /* Requires fl->size >= numWords + MinChunkSize */
1888 FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList* fl, 1890 FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList<FreeChunk>* fl,
1889 size_t numWords) { 1891 size_t numWords) {
1890 FreeChunk *curr = fl->head(); 1892 FreeChunk *curr = fl->head();
1891 size_t oldNumWords = curr->size(); 1893 size_t oldNumWords = curr->size();
1892 assert(numWords >= MinChunkSize, "Word size is too small"); 1894 assert(numWords >= MinChunkSize, "Word size is too small");
1893 assert(curr != NULL, "List is empty"); 1895 assert(curr != NULL, "List is empty");
2165 float inter_sweep_estimate, 2167 float inter_sweep_estimate,
2166 float intra_sweep_estimate) { 2168 float intra_sweep_estimate) {
2167 assert_locked(); 2169 assert_locked();
2168 size_t i; 2170 size_t i;
2169 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 2171 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2170 FreeList* fl = &_indexedFreeList[i]; 2172 FreeList<FreeChunk>* fl = &_indexedFreeList[i];
2171 if (PrintFLSStatistics > 1) { 2173 if (PrintFLSStatistics > 1) {
2172 gclog_or_tty->print("size[%d] : ", i); 2174 gclog_or_tty->print("size[%d] : ", i);
2173 } 2175 }
2174 fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate); 2176 fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate);
2175 fl->set_coalDesired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent)); 2177 fl->set_coalDesired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent));
2184 2186
2185 void CompactibleFreeListSpace::setFLSurplus() { 2187 void CompactibleFreeListSpace::setFLSurplus() {
2186 assert_locked(); 2188 assert_locked();
2187 size_t i; 2189 size_t i;
2188 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 2190 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2189 FreeList *fl = &_indexedFreeList[i]; 2191 FreeList<FreeChunk> *fl = &_indexedFreeList[i];
2190 fl->set_surplus(fl->count() - 2192 fl->set_surplus(fl->count() -
2191 (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent)); 2193 (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent));
2192 } 2194 }
2193 } 2195 }
2194 2196
2195 void CompactibleFreeListSpace::setFLHints() { 2197 void CompactibleFreeListSpace::setFLHints() {
2196 assert_locked(); 2198 assert_locked();
2197 size_t i; 2199 size_t i;
2198 size_t h = IndexSetSize; 2200 size_t h = IndexSetSize;
2199 for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) { 2201 for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) {
2200 FreeList *fl = &_indexedFreeList[i]; 2202 FreeList<FreeChunk> *fl = &_indexedFreeList[i];
2201 fl->set_hint(h); 2203 fl->set_hint(h);
2202 if (fl->surplus() > 0) { 2204 if (fl->surplus() > 0) {
2203 h = i; 2205 h = i;
2204 } 2206 }
2205 } 2207 }
2207 2209
2208 void CompactibleFreeListSpace::clearFLCensus() { 2210 void CompactibleFreeListSpace::clearFLCensus() {
2209 assert_locked(); 2211 assert_locked();
2210 size_t i; 2212 size_t i;
2211 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 2213 for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2212 FreeList *fl = &_indexedFreeList[i]; 2214 FreeList<FreeChunk> *fl = &_indexedFreeList[i];
2213 fl->set_prevSweep(fl->count()); 2215 fl->set_prevSweep(fl->count());
2214 fl->set_coalBirths(0); 2216 fl->set_coalBirths(0);
2215 fl->set_coalDeaths(0); 2217 fl->set_coalDeaths(0);
2216 fl->set_splitBirths(0); 2218 fl->set_splitBirths(0);
2217 fl->set_splitDeaths(0); 2219 fl->set_splitDeaths(0);
2234 _dictionary->endSweepDictCensus(CMSLargeSplitSurplusPercent); 2236 _dictionary->endSweepDictCensus(CMSLargeSplitSurplusPercent);
2235 } 2237 }
2236 2238
2237 bool CompactibleFreeListSpace::coalOverPopulated(size_t size) { 2239 bool CompactibleFreeListSpace::coalOverPopulated(size_t size) {
2238 if (size < SmallForDictionary) { 2240 if (size < SmallForDictionary) {
2239 FreeList *fl = &_indexedFreeList[size]; 2241 FreeList<FreeChunk> *fl = &_indexedFreeList[size];
2240 return (fl->coalDesired() < 0) || 2242 return (fl->coalDesired() < 0) ||
2241 ((int)fl->count() > fl->coalDesired()); 2243 ((int)fl->count() > fl->coalDesired());
2242 } else { 2244 } else {
2243 return dictionary()->coalDictOverPopulated(size); 2245 return dictionary()->coalDictOverPopulated(size);
2244 } 2246 }
2245 } 2247 }
2246 2248
2247 void CompactibleFreeListSpace::smallCoalBirth(size_t size) { 2249 void CompactibleFreeListSpace::smallCoalBirth(size_t size) {
2248 assert(size < SmallForDictionary, "Size too large for indexed list"); 2250 assert(size < SmallForDictionary, "Size too large for indexed list");
2249 FreeList *fl = &_indexedFreeList[size]; 2251 FreeList<FreeChunk> *fl = &_indexedFreeList[size];
2250 fl->increment_coalBirths(); 2252 fl->increment_coalBirths();
2251 fl->increment_surplus(); 2253 fl->increment_surplus();
2252 } 2254 }
2253 2255
2254 void CompactibleFreeListSpace::smallCoalDeath(size_t size) { 2256 void CompactibleFreeListSpace::smallCoalDeath(size_t size) {
2255 assert(size < SmallForDictionary, "Size too large for indexed list"); 2257 assert(size < SmallForDictionary, "Size too large for indexed list");
2256 FreeList *fl = &_indexedFreeList[size]; 2258 FreeList<FreeChunk> *fl = &_indexedFreeList[size];
2257 fl->increment_coalDeaths(); 2259 fl->increment_coalDeaths();
2258 fl->decrement_surplus(); 2260 fl->decrement_surplus();
2259 } 2261 }
2260 2262
2261 void CompactibleFreeListSpace::coalBirth(size_t size) { 2263 void CompactibleFreeListSpace::coalBirth(size_t size) {
2278 } 2280 }
2279 } 2281 }
2280 2282
2281 void CompactibleFreeListSpace::smallSplitBirth(size_t size) { 2283 void CompactibleFreeListSpace::smallSplitBirth(size_t size) {
2282 assert(size < SmallForDictionary, "Size too large for indexed list"); 2284 assert(size < SmallForDictionary, "Size too large for indexed list");
2283 FreeList *fl = &_indexedFreeList[size]; 2285 FreeList<FreeChunk> *fl = &_indexedFreeList[size];
2284 fl->increment_splitBirths(); 2286 fl->increment_splitBirths();
2285 fl->increment_surplus(); 2287 fl->increment_surplus();
2286 } 2288 }
2287 2289
2288 void CompactibleFreeListSpace::smallSplitDeath(size_t size) { 2290 void CompactibleFreeListSpace::smallSplitDeath(size_t size) {
2289 assert(size < SmallForDictionary, "Size too large for indexed list"); 2291 assert(size < SmallForDictionary, "Size too large for indexed list");
2290 FreeList *fl = &_indexedFreeList[size]; 2292 FreeList<FreeChunk> *fl = &_indexedFreeList[size];
2291 fl->increment_splitDeaths(); 2293 fl->increment_splitDeaths();
2292 fl->decrement_surplus(); 2294 fl->decrement_surplus();
2293 } 2295 }
2294 2296
2295 void CompactibleFreeListSpace::splitBirth(size_t size) { 2297 void CompactibleFreeListSpace::splitBirth(size_t size) {
2528 #ifndef PRODUCT 2530 #ifndef PRODUCT
2529 void CompactibleFreeListSpace::check_free_list_consistency() const { 2531 void CompactibleFreeListSpace::check_free_list_consistency() const {
2530 assert(_dictionary->minSize() <= IndexSetSize, 2532 assert(_dictionary->minSize() <= IndexSetSize,
2531 "Some sizes can't be allocated without recourse to" 2533 "Some sizes can't be allocated without recourse to"
2532 " linear allocation buffers"); 2534 " linear allocation buffers");
2533 assert(MIN_TREE_CHUNK_SIZE*HeapWordSize == sizeof(TreeChunk), 2535 assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>),
2534 "else MIN_TREE_CHUNK_SIZE is wrong"); 2536 "else MIN_TREE_CHUNK_SIZE is wrong");
2535 assert((IndexSetStride == 2 && IndexSetStart == 4) || // 32-bit 2537 assert((IndexSetStride == 2 && IndexSetStart == 4) || // 32-bit
2536 (IndexSetStride == 1 && IndexSetStart == 3), "just checking"); // 64-bit 2538 (IndexSetStride == 1 && IndexSetStart == 3), "just checking"); // 64-bit
2537 assert((IndexSetStride != 2) || (IndexSetStart % 2 == 0), 2539 assert((IndexSetStride != 2) || (IndexSetStart % 2 == 0),
2538 "Some for-loops may be incorrectly initialized"); 2540 "Some for-loops may be incorrectly initialized");
2541 } 2543 }
2542 #endif 2544 #endif
2543 2545
2544 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const { 2546 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
2545 assert_lock_strong(&_freelistLock); 2547 assert_lock_strong(&_freelistLock);
2546 FreeList total; 2548 FreeList<FreeChunk> total;
2547 gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count); 2549 gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count);
2548 FreeList::print_labels_on(gclog_or_tty, "size"); 2550 FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
2549 size_t totalFree = 0; 2551 size_t totalFree = 0;
2550 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { 2552 for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2551 const FreeList *fl = &_indexedFreeList[i]; 2553 const FreeList<FreeChunk> *fl = &_indexedFreeList[i];
2552 totalFree += fl->count() * fl->size(); 2554 totalFree += fl->count() * fl->size();
2553 if (i % (40*IndexSetStride) == 0) { 2555 if (i % (40*IndexSetStride) == 0) {
2554 FreeList::print_labels_on(gclog_or_tty, "size"); 2556 FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
2555 } 2557 }
2556 fl->print_on(gclog_or_tty); 2558 fl->print_on(gclog_or_tty);
2557 total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() ); 2559 total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() );
2558 total.set_surplus( total.surplus() + fl->surplus() ); 2560 total.set_surplus( total.surplus() + fl->surplus() );
2559 total.set_desired( total.desired() + fl->desired() ); 2561 total.set_desired( total.desired() + fl->desired() );
2632 MutexLockerEx x(_cfls->parDictionaryAllocLock(), 2634 MutexLockerEx x(_cfls->parDictionaryAllocLock(),
2633 Mutex::_no_safepoint_check_flag); 2635 Mutex::_no_safepoint_check_flag);
2634 res = _cfls->getChunkFromDictionaryExact(word_sz); 2636 res = _cfls->getChunkFromDictionaryExact(word_sz);
2635 if (res == NULL) return NULL; 2637 if (res == NULL) return NULL;
2636 } else { 2638 } else {
2637 FreeList* fl = &_indexedFreeList[word_sz]; 2639 FreeList<FreeChunk>* fl = &_indexedFreeList[word_sz];
2638 if (fl->count() == 0) { 2640 if (fl->count() == 0) {
2639 // Attempt to refill this local free list. 2641 // Attempt to refill this local free list.
2640 get_from_global_pool(word_sz, fl); 2642 get_from_global_pool(word_sz, fl);
2641 // If it didn't work, give up. 2643 // If it didn't work, give up.
2642 if (fl->count() == 0) return NULL; 2644 if (fl->count() == 0) return NULL;
2652 return (HeapWord*)res; 2654 return (HeapWord*)res;
2653 } 2655 }
2654 2656
2655 // Get a chunk of blocks of the right size and update related 2657 // Get a chunk of blocks of the right size and update related
2656 // book-keeping stats 2658 // book-keeping stats
2657 void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList* fl) { 2659 void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList<FreeChunk>* fl) {
2658 // Get the #blocks we want to claim 2660 // Get the #blocks we want to claim
2659 size_t n_blks = (size_t)_blocks_to_claim[word_sz].average(); 2661 size_t n_blks = (size_t)_blocks_to_claim[word_sz].average();
2660 assert(n_blks > 0, "Error"); 2662 assert(n_blks > 0, "Error");
2661 assert(ResizePLAB || n_blks == OldPLABSize, "Error"); 2663 assert(ResizePLAB || n_blks == OldPLABSize, "Error");
2662 // In some cases, when the application has a phase change, 2664 // In some cases, when the application has a phase change,
2734 _global_num_workers[i]++; 2736 _global_num_workers[i]++;
2735 assert(_global_num_workers[i] <= ParallelGCThreads, "Too big"); 2737 assert(_global_num_workers[i] <= ParallelGCThreads, "Too big");
2736 if (num_retire > 0) { 2738 if (num_retire > 0) {
2737 _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]); 2739 _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]);
2738 // Reset this list. 2740 // Reset this list.
2739 _indexedFreeList[i] = FreeList(); 2741 _indexedFreeList[i] = FreeList<FreeChunk>();
2740 _indexedFreeList[i].set_size(i); 2742 _indexedFreeList[i].set_size(i);
2741 } 2743 }
2742 } 2744 }
2743 if (PrintOldPLAB) { 2745 if (PrintOldPLAB) {
2744 gclog_or_tty->print_cr("%d[%d]: %d/%d/%d", 2746 gclog_or_tty->print_cr("%d[%d]: %d/%d/%d",
2748 _num_blocks[i] = 0; 2750 _num_blocks[i] = 0;
2749 } 2751 }
2750 } 2752 }
2751 } 2753 }
2752 2754
2753 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) { 2755 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList<FreeChunk>* fl) {
2754 assert(fl->count() == 0, "Precondition."); 2756 assert(fl->count() == 0, "Precondition.");
2755 assert(word_sz < CompactibleFreeListSpace::IndexSetSize, 2757 assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
2756 "Precondition"); 2758 "Precondition");
2757 2759
2758 // We'll try all multiples of word_sz in the indexed set, starting with 2760 // We'll try all multiples of word_sz in the indexed set, starting with
2764 size_t cur_sz; 2766 size_t cur_sz;
2765 for (k = 1, cur_sz = k * word_sz, found = false; 2767 for (k = 1, cur_sz = k * word_sz, found = false;
2766 (cur_sz < CompactibleFreeListSpace::IndexSetSize) && 2768 (cur_sz < CompactibleFreeListSpace::IndexSetSize) &&
2767 (CMSSplitIndexedFreeListBlocks || k <= 1); 2769 (CMSSplitIndexedFreeListBlocks || k <= 1);
2768 k++, cur_sz = k * word_sz) { 2770 k++, cur_sz = k * word_sz) {
2769 FreeList fl_for_cur_sz; // Empty. 2771 FreeList<FreeChunk> fl_for_cur_sz; // Empty.
2770 fl_for_cur_sz.set_size(cur_sz); 2772 fl_for_cur_sz.set_size(cur_sz);
2771 { 2773 {
2772 MutexLockerEx x(_indexedFreeListParLocks[cur_sz], 2774 MutexLockerEx x(_indexedFreeListParLocks[cur_sz],
2773 Mutex::_no_safepoint_check_flag); 2775 Mutex::_no_safepoint_check_flag);
2774 FreeList* gfl = &_indexedFreeList[cur_sz]; 2776 FreeList<FreeChunk>* gfl = &_indexedFreeList[cur_sz];
2775 if (gfl->count() != 0) { 2777 if (gfl->count() != 0) {
2776 // nn is the number of chunks of size cur_sz that 2778 // nn is the number of chunks of size cur_sz that
2777 // we'd need to split k-ways each, in order to create 2779 // we'd need to split k-ways each, in order to create
2778 // "n" chunks of size word_sz each. 2780 // "n" chunks of size word_sz each.
2779 const size_t nn = MAX2(n/k, (size_t)1); 2781 const size_t nn = MAX2(n/k, (size_t)1);
2846 MutexLockerEx x(parDictionaryAllocLock(), 2848 MutexLockerEx x(parDictionaryAllocLock(),
2847 Mutex::_no_safepoint_check_flag); 2849 Mutex::_no_safepoint_check_flag);
2848 while (n > 0) { 2850 while (n > 0) {
2849 fc = dictionary()->getChunk(MAX2(n * word_sz, 2851 fc = dictionary()->getChunk(MAX2(n * word_sz,
2850 _dictionary->minSize()), 2852 _dictionary->minSize()),
2851 FreeBlockDictionary::atLeast); 2853 FreeBlockDictionary<FreeChunk>::atLeast);
2852 if (fc != NULL) { 2854 if (fc != NULL) {
2853 _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk 2855 _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk
2854 dictionary()->dictCensusUpdate(fc->size(), 2856 dictionary()->dictCensusUpdate(fc->size(),
2855 true /*split*/, 2857 true /*split*/,
2856 false /*birth*/); 2858 false /*birth*/);

mercurial