hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
changeset 12507 6182ca66bc7b
parent 12379 2cf45b79ce3a
child 12509 6228e2085074
--- 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(),