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

changeset 3730
9f059abe8cf2
parent 3711
b632e80fc9dc
child 3732
f69a5d43dc19
     1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Fri Apr 20 17:13:36 2012 -0700
     1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Thu Mar 29 19:46:24 2012 -0700
     1.3 @@ -69,7 +69,7 @@
     1.4  // Constructor
     1.5  CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
     1.6    MemRegion mr, bool use_adaptive_freelists,
     1.7 -  FreeBlockDictionary::DictionaryChoice dictionaryChoice) :
     1.8 +  FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
     1.9    _dictionaryChoice(dictionaryChoice),
    1.10    _adaptive_freelists(use_adaptive_freelists),
    1.11    _bt(bs, mr),
    1.12 @@ -87,6 +87,8 @@
    1.13                      CMSConcMarkMultiple),
    1.14    _collector(NULL)
    1.15  {
    1.16 +  assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize,
    1.17 +    "FreeChunk is larger than expected");
    1.18    _bt.set_space(this);
    1.19    initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
    1.20    // We have all of "mr", all of which we place in the dictionary
    1.21 @@ -96,13 +98,13 @@
    1.22    // implementation, namely, the simple binary tree (splaying
    1.23    // temporarily disabled).
    1.24    switch (dictionaryChoice) {
    1.25 -    case FreeBlockDictionary::dictionarySplayTree:
    1.26 -    case FreeBlockDictionary::dictionarySkipList:
    1.27 +    case FreeBlockDictionary<FreeChunk>::dictionarySplayTree:
    1.28 +    case FreeBlockDictionary<FreeChunk>::dictionarySkipList:
    1.29      default:
    1.30        warning("dictionaryChoice: selected option not understood; using"
    1.31                " default BinaryTreeDictionary implementation instead.");
    1.32 -    case FreeBlockDictionary::dictionaryBinaryTree:
    1.33 -      _dictionary = new BinaryTreeDictionary(mr);
    1.34 +    case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree:
    1.35 +      _dictionary = new BinaryTreeDictionary<FreeChunk>(mr, use_adaptive_freelists);
    1.36        break;
    1.37    }
    1.38    assert(_dictionary != NULL, "CMS dictionary initialization");
    1.39 @@ -448,7 +450,7 @@
    1.40    reportIndexedFreeListStatistics();
    1.41    gclog_or_tty->print_cr("Layout of Indexed Freelists");
    1.42    gclog_or_tty->print_cr("---------------------------");
    1.43 -  FreeList::print_labels_on(st, "size");
    1.44 +  FreeList<FreeChunk>::print_labels_on(st, "size");
    1.45    for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
    1.46      _indexedFreeList[i].print_on(gclog_or_tty);
    1.47      for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
    1.48 @@ -1331,7 +1333,7 @@
    1.49    size_t currSize = numWords + MinChunkSize;
    1.50    assert(currSize % MinObjAlignment == 0, "currSize should be aligned");
    1.51    for (i = currSize; i < IndexSetSize; i += IndexSetStride) {
    1.52 -    FreeList* fl = &_indexedFreeList[i];
    1.53 +    FreeList<FreeChunk>* fl = &_indexedFreeList[i];
    1.54      if (fl->head()) {
    1.55        ret = getFromListGreater(fl, numWords);
    1.56        assert(ret == NULL || ret->isFree(), "Should be returning a free chunk");
    1.57 @@ -1714,7 +1716,7 @@
    1.58    _dictionary->returnChunk(chunk);
    1.59  #ifndef PRODUCT
    1.60    if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
    1.61 -    TreeChunk::as_TreeChunk(chunk)->list()->verify_stats();
    1.62 +    TreeChunk<FreeChunk>::as_TreeChunk(chunk)->list()->verify_stats();
    1.63    }
    1.64  #endif // PRODUCT
    1.65  }
    1.66 @@ -1862,11 +1864,11 @@
    1.67       the excess is >= MIN_CHUNK. */
    1.68    size_t start = align_object_size(numWords + MinChunkSize);
    1.69    if (start < IndexSetSize) {
    1.70 -    FreeList* it   = _indexedFreeList;
    1.71 +    FreeList<FreeChunk>* it   = _indexedFreeList;
    1.72      size_t    hint = _indexedFreeList[start].hint();
    1.73      while (hint < IndexSetSize) {
    1.74        assert(hint % MinObjAlignment == 0, "hint should be aligned");
    1.75 -      FreeList *fl = &_indexedFreeList[hint];
    1.76 +      FreeList<FreeChunk> *fl = &_indexedFreeList[hint];
    1.77        if (fl->surplus() > 0 && fl->head() != NULL) {
    1.78          // Found a list with surplus, reset original hint
    1.79          // and split out a free chunk which is returned.
    1.80 @@ -1885,7 +1887,7 @@
    1.81  }
    1.82  
    1.83  /* Requires fl->size >= numWords + MinChunkSize */
    1.84 -FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList* fl,
    1.85 +FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList<FreeChunk>* fl,
    1.86    size_t numWords) {
    1.87    FreeChunk *curr = fl->head();
    1.88    size_t oldNumWords = curr->size();
    1.89 @@ -2167,7 +2169,7 @@
    1.90    assert_locked();
    1.91    size_t i;
    1.92    for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
    1.93 -    FreeList* fl    = &_indexedFreeList[i];
    1.94 +    FreeList<FreeChunk>* fl = &_indexedFreeList[i];
    1.95      if (PrintFLSStatistics > 1) {
    1.96        gclog_or_tty->print("size[%d] : ", i);
    1.97      }
    1.98 @@ -2186,7 +2188,7 @@
    1.99    assert_locked();
   1.100    size_t i;
   1.101    for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
   1.102 -    FreeList *fl = &_indexedFreeList[i];
   1.103 +    FreeList<FreeChunk> *fl = &_indexedFreeList[i];
   1.104      fl->set_surplus(fl->count() -
   1.105                      (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent));
   1.106    }
   1.107 @@ -2197,7 +2199,7 @@
   1.108    size_t i;
   1.109    size_t h = IndexSetSize;
   1.110    for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) {
   1.111 -    FreeList *fl = &_indexedFreeList[i];
   1.112 +    FreeList<FreeChunk> *fl = &_indexedFreeList[i];
   1.113      fl->set_hint(h);
   1.114      if (fl->surplus() > 0) {
   1.115        h = i;
   1.116 @@ -2209,7 +2211,7 @@
   1.117    assert_locked();
   1.118    size_t i;
   1.119    for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
   1.120 -    FreeList *fl = &_indexedFreeList[i];
   1.121 +    FreeList<FreeChunk> *fl = &_indexedFreeList[i];
   1.122      fl->set_prevSweep(fl->count());
   1.123      fl->set_coalBirths(0);
   1.124      fl->set_coalDeaths(0);
   1.125 @@ -2236,7 +2238,7 @@
   1.126  
   1.127  bool CompactibleFreeListSpace::coalOverPopulated(size_t size) {
   1.128    if (size < SmallForDictionary) {
   1.129 -    FreeList *fl = &_indexedFreeList[size];
   1.130 +    FreeList<FreeChunk> *fl = &_indexedFreeList[size];
   1.131      return (fl->coalDesired() < 0) ||
   1.132             ((int)fl->count() > fl->coalDesired());
   1.133    } else {
   1.134 @@ -2246,14 +2248,14 @@
   1.135  
   1.136  void CompactibleFreeListSpace::smallCoalBirth(size_t size) {
   1.137    assert(size < SmallForDictionary, "Size too large for indexed list");
   1.138 -  FreeList *fl = &_indexedFreeList[size];
   1.139 +  FreeList<FreeChunk> *fl = &_indexedFreeList[size];
   1.140    fl->increment_coalBirths();
   1.141    fl->increment_surplus();
   1.142  }
   1.143  
   1.144  void CompactibleFreeListSpace::smallCoalDeath(size_t size) {
   1.145    assert(size < SmallForDictionary, "Size too large for indexed list");
   1.146 -  FreeList *fl = &_indexedFreeList[size];
   1.147 +  FreeList<FreeChunk> *fl = &_indexedFreeList[size];
   1.148    fl->increment_coalDeaths();
   1.149    fl->decrement_surplus();
   1.150  }
   1.151 @@ -2280,14 +2282,14 @@
   1.152  
   1.153  void CompactibleFreeListSpace::smallSplitBirth(size_t size) {
   1.154    assert(size < SmallForDictionary, "Size too large for indexed list");
   1.155 -  FreeList *fl = &_indexedFreeList[size];
   1.156 +  FreeList<FreeChunk> *fl = &_indexedFreeList[size];
   1.157    fl->increment_splitBirths();
   1.158    fl->increment_surplus();
   1.159  }
   1.160  
   1.161  void CompactibleFreeListSpace::smallSplitDeath(size_t size) {
   1.162    assert(size < SmallForDictionary, "Size too large for indexed list");
   1.163 -  FreeList *fl = &_indexedFreeList[size];
   1.164 +  FreeList<FreeChunk> *fl = &_indexedFreeList[size];
   1.165    fl->increment_splitDeaths();
   1.166    fl->decrement_surplus();
   1.167  }
   1.168 @@ -2530,7 +2532,7 @@
   1.169    assert(_dictionary->minSize() <= IndexSetSize,
   1.170      "Some sizes can't be allocated without recourse to"
   1.171      " linear allocation buffers");
   1.172 -  assert(MIN_TREE_CHUNK_SIZE*HeapWordSize == sizeof(TreeChunk),
   1.173 +  assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>),
   1.174      "else MIN_TREE_CHUNK_SIZE is wrong");
   1.175    assert((IndexSetStride == 2 && IndexSetStart == 4) ||                   // 32-bit
   1.176           (IndexSetStride == 1 && IndexSetStart == 3), "just checking");   // 64-bit
   1.177 @@ -2543,15 +2545,15 @@
   1.178  
   1.179  void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
   1.180    assert_lock_strong(&_freelistLock);
   1.181 -  FreeList total;
   1.182 +  FreeList<FreeChunk> total;
   1.183    gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count);
   1.184 -  FreeList::print_labels_on(gclog_or_tty, "size");
   1.185 +  FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
   1.186    size_t totalFree = 0;
   1.187    for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
   1.188 -    const FreeList *fl = &_indexedFreeList[i];
   1.189 +    const FreeList<FreeChunk> *fl = &_indexedFreeList[i];
   1.190      totalFree += fl->count() * fl->size();
   1.191      if (i % (40*IndexSetStride) == 0) {
   1.192 -      FreeList::print_labels_on(gclog_or_tty, "size");
   1.193 +      FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
   1.194      }
   1.195      fl->print_on(gclog_or_tty);
   1.196      total.set_bfrSurp(    total.bfrSurp()     + fl->bfrSurp()    );
   1.197 @@ -2634,7 +2636,7 @@
   1.198      res = _cfls->getChunkFromDictionaryExact(word_sz);
   1.199      if (res == NULL) return NULL;
   1.200    } else {
   1.201 -    FreeList* fl = &_indexedFreeList[word_sz];
   1.202 +    FreeList<FreeChunk>* fl = &_indexedFreeList[word_sz];
   1.203      if (fl->count() == 0) {
   1.204        // Attempt to refill this local free list.
   1.205        get_from_global_pool(word_sz, fl);
   1.206 @@ -2654,7 +2656,7 @@
   1.207  
   1.208  // Get a chunk of blocks of the right size and update related
   1.209  // book-keeping stats
   1.210 -void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList* fl) {
   1.211 +void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList<FreeChunk>* fl) {
   1.212    // Get the #blocks we want to claim
   1.213    size_t n_blks = (size_t)_blocks_to_claim[word_sz].average();
   1.214    assert(n_blks > 0, "Error");
   1.215 @@ -2736,7 +2738,7 @@
   1.216          if (num_retire > 0) {
   1.217            _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]);
   1.218            // Reset this list.
   1.219 -          _indexedFreeList[i] = FreeList();
   1.220 +          _indexedFreeList[i] = FreeList<FreeChunk>();
   1.221            _indexedFreeList[i].set_size(i);
   1.222          }
   1.223        }
   1.224 @@ -2750,7 +2752,7 @@
   1.225    }
   1.226  }
   1.227  
   1.228 -void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) {
   1.229 +void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList<FreeChunk>* fl) {
   1.230    assert(fl->count() == 0, "Precondition.");
   1.231    assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
   1.232           "Precondition");
   1.233 @@ -2766,12 +2768,12 @@
   1.234           (cur_sz < CompactibleFreeListSpace::IndexSetSize) &&
   1.235           (CMSSplitIndexedFreeListBlocks || k <= 1);
   1.236           k++, cur_sz = k * word_sz) {
   1.237 -      FreeList fl_for_cur_sz;  // Empty.
   1.238 +      FreeList<FreeChunk> fl_for_cur_sz;  // Empty.
   1.239        fl_for_cur_sz.set_size(cur_sz);
   1.240        {
   1.241          MutexLockerEx x(_indexedFreeListParLocks[cur_sz],
   1.242                          Mutex::_no_safepoint_check_flag);
   1.243 -        FreeList* gfl = &_indexedFreeList[cur_sz];
   1.244 +        FreeList<FreeChunk>* gfl = &_indexedFreeList[cur_sz];
   1.245          if (gfl->count() != 0) {
   1.246            // nn is the number of chunks of size cur_sz that
   1.247            // we'd need to split k-ways each, in order to create
   1.248 @@ -2848,7 +2850,7 @@
   1.249      while (n > 0) {
   1.250        fc = dictionary()->getChunk(MAX2(n * word_sz,
   1.251                                    _dictionary->minSize()),
   1.252 -                                  FreeBlockDictionary::atLeast);
   1.253 +                                  FreeBlockDictionary<FreeChunk>::atLeast);
   1.254        if (fc != NULL) {
   1.255          _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */);  // update _unallocated_blk
   1.256          dictionary()->dictCensusUpdate(fc->size(),

mercurial