--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Apr 20 17:13:36 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Mar 29 19:46:24 2012 -0700
@@ -69,7 +69,7 @@
// Constructor
CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
MemRegion mr, bool use_adaptive_freelists,
- FreeBlockDictionary::DictionaryChoice dictionaryChoice) :
+ FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
_dictionaryChoice(dictionaryChoice),
_adaptive_freelists(use_adaptive_freelists),
_bt(bs, mr),
@@ -87,6 +87,8 @@
CMSConcMarkMultiple),
_collector(NULL)
{
+ assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize,
+ "FreeChunk is larger than expected");
_bt.set_space(this);
initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
// We have all of "mr", all of which we place in the dictionary
@@ -96,13 +98,13 @@
// implementation, namely, the simple binary tree (splaying
// temporarily disabled).
switch (dictionaryChoice) {
- case FreeBlockDictionary::dictionarySplayTree:
- case FreeBlockDictionary::dictionarySkipList:
+ case FreeBlockDictionary<FreeChunk>::dictionarySplayTree:
+ case FreeBlockDictionary<FreeChunk>::dictionarySkipList:
default:
warning("dictionaryChoice: selected option not understood; using"
" default BinaryTreeDictionary implementation instead.");
- case FreeBlockDictionary::dictionaryBinaryTree:
- _dictionary = new BinaryTreeDictionary(mr);
+ case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree:
+ _dictionary = new BinaryTreeDictionary<FreeChunk>(mr, use_adaptive_freelists);
break;
}
assert(_dictionary != NULL, "CMS dictionary initialization");
@@ -448,7 +450,7 @@
reportIndexedFreeListStatistics();
gclog_or_tty->print_cr("Layout of Indexed Freelists");
gclog_or_tty->print_cr("---------------------------");
- FreeList::print_labels_on(st, "size");
+ FreeList<FreeChunk>::print_labels_on(st, "size");
for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
_indexedFreeList[i].print_on(gclog_or_tty);
for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
@@ -1331,7 +1333,7 @@
size_t currSize = numWords + MinChunkSize;
assert(currSize % MinObjAlignment == 0, "currSize should be aligned");
for (i = currSize; i < IndexSetSize; i += IndexSetStride) {
- FreeList* fl = &_indexedFreeList[i];
+ FreeList<FreeChunk>* fl = &_indexedFreeList[i];
if (fl->head()) {
ret = getFromListGreater(fl, numWords);
assert(ret == NULL || ret->isFree(), "Should be returning a free chunk");
@@ -1714,7 +1716,7 @@
_dictionary->returnChunk(chunk);
#ifndef PRODUCT
if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
- TreeChunk::as_TreeChunk(chunk)->list()->verify_stats();
+ TreeChunk<FreeChunk>::as_TreeChunk(chunk)->list()->verify_stats();
}
#endif // PRODUCT
}
@@ -1862,11 +1864,11 @@
the excess is >= MIN_CHUNK. */
size_t start = align_object_size(numWords + MinChunkSize);
if (start < IndexSetSize) {
- FreeList* it = _indexedFreeList;
+ FreeList<FreeChunk>* it = _indexedFreeList;
size_t hint = _indexedFreeList[start].hint();
while (hint < IndexSetSize) {
assert(hint % MinObjAlignment == 0, "hint should be aligned");
- FreeList *fl = &_indexedFreeList[hint];
+ FreeList<FreeChunk> *fl = &_indexedFreeList[hint];
if (fl->surplus() > 0 && fl->head() != NULL) {
// Found a list with surplus, reset original hint
// and split out a free chunk which is returned.
@@ -1885,7 +1887,7 @@
}
/* Requires fl->size >= numWords + MinChunkSize */
-FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList* fl,
+FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList<FreeChunk>* fl,
size_t numWords) {
FreeChunk *curr = fl->head();
size_t oldNumWords = curr->size();
@@ -2167,7 +2169,7 @@
assert_locked();
size_t i;
for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
- FreeList* fl = &_indexedFreeList[i];
+ FreeList<FreeChunk>* fl = &_indexedFreeList[i];
if (PrintFLSStatistics > 1) {
gclog_or_tty->print("size[%d] : ", i);
}
@@ -2186,7 +2188,7 @@
assert_locked();
size_t i;
for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
- FreeList *fl = &_indexedFreeList[i];
+ FreeList<FreeChunk> *fl = &_indexedFreeList[i];
fl->set_surplus(fl->count() -
(ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent));
}
@@ -2197,7 +2199,7 @@
size_t i;
size_t h = IndexSetSize;
for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) {
- FreeList *fl = &_indexedFreeList[i];
+ FreeList<FreeChunk> *fl = &_indexedFreeList[i];
fl->set_hint(h);
if (fl->surplus() > 0) {
h = i;
@@ -2209,7 +2211,7 @@
assert_locked();
size_t i;
for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
- FreeList *fl = &_indexedFreeList[i];
+ FreeList<FreeChunk> *fl = &_indexedFreeList[i];
fl->set_prevSweep(fl->count());
fl->set_coalBirths(0);
fl->set_coalDeaths(0);
@@ -2236,7 +2238,7 @@
bool CompactibleFreeListSpace::coalOverPopulated(size_t size) {
if (size < SmallForDictionary) {
- FreeList *fl = &_indexedFreeList[size];
+ FreeList<FreeChunk> *fl = &_indexedFreeList[size];
return (fl->coalDesired() < 0) ||
((int)fl->count() > fl->coalDesired());
} else {
@@ -2246,14 +2248,14 @@
void CompactibleFreeListSpace::smallCoalBirth(size_t size) {
assert(size < SmallForDictionary, "Size too large for indexed list");
- FreeList *fl = &_indexedFreeList[size];
+ FreeList<FreeChunk> *fl = &_indexedFreeList[size];
fl->increment_coalBirths();
fl->increment_surplus();
}
void CompactibleFreeListSpace::smallCoalDeath(size_t size) {
assert(size < SmallForDictionary, "Size too large for indexed list");
- FreeList *fl = &_indexedFreeList[size];
+ FreeList<FreeChunk> *fl = &_indexedFreeList[size];
fl->increment_coalDeaths();
fl->decrement_surplus();
}
@@ -2280,14 +2282,14 @@
void CompactibleFreeListSpace::smallSplitBirth(size_t size) {
assert(size < SmallForDictionary, "Size too large for indexed list");
- FreeList *fl = &_indexedFreeList[size];
+ FreeList<FreeChunk> *fl = &_indexedFreeList[size];
fl->increment_splitBirths();
fl->increment_surplus();
}
void CompactibleFreeListSpace::smallSplitDeath(size_t size) {
assert(size < SmallForDictionary, "Size too large for indexed list");
- FreeList *fl = &_indexedFreeList[size];
+ FreeList<FreeChunk> *fl = &_indexedFreeList[size];
fl->increment_splitDeaths();
fl->decrement_surplus();
}
@@ -2530,7 +2532,7 @@
assert(_dictionary->minSize() <= IndexSetSize,
"Some sizes can't be allocated without recourse to"
" linear allocation buffers");
- assert(MIN_TREE_CHUNK_SIZE*HeapWordSize == sizeof(TreeChunk),
+ assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>),
"else MIN_TREE_CHUNK_SIZE is wrong");
assert((IndexSetStride == 2 && IndexSetStart == 4) || // 32-bit
(IndexSetStride == 1 && IndexSetStart == 3), "just checking"); // 64-bit
@@ -2543,15 +2545,15 @@
void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
assert_lock_strong(&_freelistLock);
- FreeList total;
+ FreeList<FreeChunk> total;
gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count);
- FreeList::print_labels_on(gclog_or_tty, "size");
+ FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
size_t totalFree = 0;
for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
- const FreeList *fl = &_indexedFreeList[i];
+ const FreeList<FreeChunk> *fl = &_indexedFreeList[i];
totalFree += fl->count() * fl->size();
if (i % (40*IndexSetStride) == 0) {
- FreeList::print_labels_on(gclog_or_tty, "size");
+ FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
}
fl->print_on(gclog_or_tty);
total.set_bfrSurp( total.bfrSurp() + fl->bfrSurp() );
@@ -2634,7 +2636,7 @@
res = _cfls->getChunkFromDictionaryExact(word_sz);
if (res == NULL) return NULL;
} else {
- FreeList* fl = &_indexedFreeList[word_sz];
+ FreeList<FreeChunk>* fl = &_indexedFreeList[word_sz];
if (fl->count() == 0) {
// Attempt to refill this local free list.
get_from_global_pool(word_sz, fl);
@@ -2654,7 +2656,7 @@
// Get a chunk of blocks of the right size and update related
// book-keeping stats
-void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList* fl) {
+void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList<FreeChunk>* fl) {
// Get the #blocks we want to claim
size_t n_blks = (size_t)_blocks_to_claim[word_sz].average();
assert(n_blks > 0, "Error");
@@ -2736,7 +2738,7 @@
if (num_retire > 0) {
_cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]);
// Reset this list.
- _indexedFreeList[i] = FreeList();
+ _indexedFreeList[i] = FreeList<FreeChunk>();
_indexedFreeList[i].set_size(i);
}
}
@@ -2750,7 +2752,7 @@
}
}
-void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) {
+void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList<FreeChunk>* fl) {
assert(fl->count() == 0, "Precondition.");
assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
"Precondition");
@@ -2766,12 +2768,12 @@
(cur_sz < CompactibleFreeListSpace::IndexSetSize) &&
(CMSSplitIndexedFreeListBlocks || k <= 1);
k++, cur_sz = k * word_sz) {
- FreeList fl_for_cur_sz; // Empty.
+ FreeList<FreeChunk> fl_for_cur_sz; // Empty.
fl_for_cur_sz.set_size(cur_sz);
{
MutexLockerEx x(_indexedFreeListParLocks[cur_sz],
Mutex::_no_safepoint_check_flag);
- FreeList* gfl = &_indexedFreeList[cur_sz];
+ FreeList<FreeChunk>* gfl = &_indexedFreeList[cur_sz];
if (gfl->count() != 0) {
// nn is the number of chunks of size cur_sz that
// we'd need to split k-ways each, in order to create
@@ -2848,7 +2850,7 @@
while (n > 0) {
fc = dictionary()->getChunk(MAX2(n * word_sz,
_dictionary->minSize()),
- FreeBlockDictionary::atLeast);
+ FreeBlockDictionary<FreeChunk>::atLeast);
if (fc != NULL) {
_bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk
dictionary()->dictCensusUpdate(fc->size(),