--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Oct 19 11:26:17 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Sep 18 23:35:42 2012 -0700
@@ -91,7 +91,7 @@
_collector(NULL)
{
assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize,
- "FreeChunk is larger than expected");
+ "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
@@ -101,14 +101,14 @@
// implementation, namely, the simple binary tree (splaying
// temporarily disabled).
switch (dictionaryChoice) {
+ case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree:
+ _dictionary = new BinaryTreeDictionary<FreeChunk, AdaptiveFreeList>(mr);
+ break;
case FreeBlockDictionary<FreeChunk>::dictionarySplayTree:
case FreeBlockDictionary<FreeChunk>::dictionarySkipList:
default:
warning("dictionaryChoice: selected option not understood; using"
" default BinaryTreeDictionary implementation instead.");
- case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree:
- _dictionary = new BinaryTreeDictionary<FreeChunk>(mr, use_adaptive_freelists);
- break;
}
assert(_dictionary != NULL, "CMS dictionary initialization");
// The indexed free lists are initially all empty and are lazily
@@ -453,7 +453,7 @@
reportIndexedFreeListStatistics();
gclog_or_tty->print_cr("Layout of Indexed Freelists");
gclog_or_tty->print_cr("---------------------------");
- FreeList<FreeChunk>::print_labels_on(st, "size");
+ AdaptiveFreeList<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;
@@ -1319,7 +1319,7 @@
size_t currSize = numWords + MinChunkSize;
assert(currSize % MinObjAlignment == 0, "currSize should be aligned");
for (i = currSize; i < IndexSetSize; i += IndexSetStride) {
- FreeList<FreeChunk>* fl = &_indexedFreeList[i];
+ AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[i];
if (fl->head()) {
ret = getFromListGreater(fl, numWords);
assert(ret == NULL || ret->is_free(), "Should be returning a free chunk");
@@ -1702,7 +1702,9 @@
_dictionary->return_chunk(chunk);
#ifndef PRODUCT
if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
- TreeChunk<FreeChunk>::as_TreeChunk(chunk)->list()->verify_stats();
+ TreeChunk<FreeChunk, AdaptiveFreeList>* tc = TreeChunk<FreeChunk, AdaptiveFreeList>::as_TreeChunk(chunk);
+ TreeList<FreeChunk, AdaptiveFreeList>* tl = tc->list();
+ tl->verify_stats();
}
#endif // PRODUCT
}
@@ -1745,7 +1747,7 @@
{
MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag);
ec = dictionary()->find_largest_dict(); // get largest block
- if (ec != NULL && ec->end() == chunk) {
+ if (ec != NULL && ec->end() == (uintptr_t*) chunk) {
// It's a coterminal block - we can coalesce.
size_t old_size = ec->size();
coalDeath(old_size);
@@ -1850,11 +1852,11 @@
the excess is >= MIN_CHUNK. */
size_t start = align_object_size(numWords + MinChunkSize);
if (start < IndexSetSize) {
- FreeList<FreeChunk>* it = _indexedFreeList;
+ AdaptiveFreeList<FreeChunk>* it = _indexedFreeList;
size_t hint = _indexedFreeList[start].hint();
while (hint < IndexSetSize) {
assert(hint % MinObjAlignment == 0, "hint should be aligned");
- FreeList<FreeChunk> *fl = &_indexedFreeList[hint];
+ AdaptiveFreeList<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.
@@ -1873,7 +1875,7 @@
}
/* Requires fl->size >= numWords + MinChunkSize */
-FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList<FreeChunk>* fl,
+FreeChunk* CompactibleFreeListSpace::getFromListGreater(AdaptiveFreeList<FreeChunk>* fl,
size_t numWords) {
FreeChunk *curr = fl->head();
size_t oldNumWords = curr->size();
@@ -2155,7 +2157,7 @@
assert_locked();
size_t i;
for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
- FreeList<FreeChunk>* fl = &_indexedFreeList[i];
+ AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[i];
if (PrintFLSStatistics > 1) {
gclog_or_tty->print("size[%d] : ", i);
}
@@ -2174,7 +2176,7 @@
assert_locked();
size_t i;
for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
- FreeList<FreeChunk> *fl = &_indexedFreeList[i];
+ AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i];
fl->set_surplus(fl->count() -
(ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent));
}
@@ -2185,7 +2187,7 @@
size_t i;
size_t h = IndexSetSize;
for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) {
- FreeList<FreeChunk> *fl = &_indexedFreeList[i];
+ AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i];
fl->set_hint(h);
if (fl->surplus() > 0) {
h = i;
@@ -2197,7 +2199,7 @@
assert_locked();
size_t i;
for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
- FreeList<FreeChunk> *fl = &_indexedFreeList[i];
+ AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i];
fl->set_prev_sweep(fl->count());
fl->set_coal_births(0);
fl->set_coal_deaths(0);
@@ -2224,7 +2226,7 @@
bool CompactibleFreeListSpace::coalOverPopulated(size_t size) {
if (size < SmallForDictionary) {
- FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+ AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size];
return (fl->coal_desired() < 0) ||
((int)fl->count() > fl->coal_desired());
} else {
@@ -2234,14 +2236,14 @@
void CompactibleFreeListSpace::smallCoalBirth(size_t size) {
assert(size < SmallForDictionary, "Size too large for indexed list");
- FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+ AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size];
fl->increment_coal_births();
fl->increment_surplus();
}
void CompactibleFreeListSpace::smallCoalDeath(size_t size) {
assert(size < SmallForDictionary, "Size too large for indexed list");
- FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+ AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size];
fl->increment_coal_deaths();
fl->decrement_surplus();
}
@@ -2250,7 +2252,7 @@
if (size < SmallForDictionary) {
smallCoalBirth(size);
} else {
- dictionary()->dict_census_udpate(size,
+ dictionary()->dict_census_update(size,
false /* split */,
true /* birth */);
}
@@ -2260,7 +2262,7 @@
if(size < SmallForDictionary) {
smallCoalDeath(size);
} else {
- dictionary()->dict_census_udpate(size,
+ dictionary()->dict_census_update(size,
false /* split */,
false /* birth */);
}
@@ -2268,14 +2270,14 @@
void CompactibleFreeListSpace::smallSplitBirth(size_t size) {
assert(size < SmallForDictionary, "Size too large for indexed list");
- FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+ AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size];
fl->increment_split_births();
fl->increment_surplus();
}
void CompactibleFreeListSpace::smallSplitDeath(size_t size) {
assert(size < SmallForDictionary, "Size too large for indexed list");
- FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+ AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[size];
fl->increment_split_deaths();
fl->decrement_surplus();
}
@@ -2284,7 +2286,7 @@
if (size < SmallForDictionary) {
smallSplitBirth(size);
} else {
- dictionary()->dict_census_udpate(size,
+ dictionary()->dict_census_update(size,
true /* split */,
true /* birth */);
}
@@ -2294,7 +2296,7 @@
if (size < SmallForDictionary) {
smallSplitDeath(size);
} else {
- dictionary()->dict_census_udpate(size,
+ dictionary()->dict_census_update(size,
true /* split */,
false /* birth */);
}
@@ -2517,10 +2519,10 @@
#ifndef PRODUCT
void CompactibleFreeListSpace::check_free_list_consistency() const {
- assert(_dictionary->min_size() <= IndexSetSize,
+ assert((TreeChunk<FreeChunk, AdaptiveFreeList>::min_size() <= IndexSetSize),
"Some sizes can't be allocated without recourse to"
" linear allocation buffers");
- assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>),
+ assert((TreeChunk<FreeChunk, AdaptiveFreeList>::min_size()*HeapWordSize == sizeof(TreeChunk<FreeChunk, AdaptiveFreeList>)),
"else MIN_TREE_CHUNK_SIZE is wrong");
assert(IndexSetStart != 0, "IndexSetStart not initialized");
assert(IndexSetStride != 0, "IndexSetStride not initialized");
@@ -2529,15 +2531,15 @@
void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
assert_lock_strong(&_freelistLock);
- FreeList<FreeChunk> total;
+ AdaptiveFreeList<FreeChunk> total;
gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count);
- FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
+ AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
size_t total_free = 0;
for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
- const FreeList<FreeChunk> *fl = &_indexedFreeList[i];
+ const AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i];
total_free += fl->count() * fl->size();
if (i % (40*IndexSetStride) == 0) {
- FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
+ AdaptiveFreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
}
fl->print_on(gclog_or_tty);
total.set_bfr_surp( total.bfr_surp() + fl->bfr_surp() );
@@ -2620,7 +2622,7 @@
res = _cfls->getChunkFromDictionaryExact(word_sz);
if (res == NULL) return NULL;
} else {
- FreeList<FreeChunk>* fl = &_indexedFreeList[word_sz];
+ AdaptiveFreeList<FreeChunk>* fl = &_indexedFreeList[word_sz];
if (fl->count() == 0) {
// Attempt to refill this local free list.
get_from_global_pool(word_sz, fl);
@@ -2640,7 +2642,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<FreeChunk>* fl) {
+void CFLS_LAB::get_from_global_pool(size_t word_sz, AdaptiveFreeList<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");
@@ -2722,7 +2724,7 @@
if (num_retire > 0) {
_cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]);
// Reset this list.
- _indexedFreeList[i] = FreeList<FreeChunk>();
+ _indexedFreeList[i] = AdaptiveFreeList<FreeChunk>();
_indexedFreeList[i].set_size(i);
}
}
@@ -2736,7 +2738,7 @@
}
}
-void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList<FreeChunk>* fl) {
+void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
assert(fl->count() == 0, "Precondition.");
assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
"Precondition");
@@ -2752,12 +2754,12 @@
(cur_sz < CompactibleFreeListSpace::IndexSetSize) &&
(CMSSplitIndexedFreeListBlocks || k <= 1);
k++, cur_sz = k * word_sz) {
- FreeList<FreeChunk> fl_for_cur_sz; // Empty.
+ AdaptiveFreeList<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<FreeChunk>* gfl = &_indexedFreeList[cur_sz];
+ AdaptiveFreeList<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
@@ -2832,12 +2834,11 @@
MutexLockerEx x(parDictionaryAllocLock(),
Mutex::_no_safepoint_check_flag);
while (n > 0) {
- fc = dictionary()->get_chunk(MAX2(n * word_sz,
- _dictionary->min_size()),
+ fc = dictionary()->get_chunk(MAX2(n * word_sz, _dictionary->min_size()),
FreeBlockDictionary<FreeChunk>::atLeast);
if (fc != NULL) {
_bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */); // update _unallocated_blk
- dictionary()->dict_census_udpate(fc->size(),
+ dictionary()->dict_census_update(fc->size(),
true /*split*/,
false /*birth*/);
break;
@@ -2890,7 +2891,7 @@
fc->set_size(prefix_size);
if (rem >= IndexSetSize) {
returnChunkToDictionary(rem_fc);
- dictionary()->dict_census_udpate(rem, true /*split*/, true /*birth*/);
+ dictionary()->dict_census_update(rem, true /*split*/, true /*birth*/);
rem_fc = NULL;
}
// Otherwise, return it to the small list below.