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

changeset 7234
4001310db3f5
parent 6980
6c523f5d5440
child 7345
a28b7832203a
child 7476
c2844108a708
     1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Fri Oct 03 13:34:46 2014 -0700
     1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Thu Nov 21 09:57:00 2013 -0800
     1.3 @@ -2733,10 +2733,12 @@
     1.4    }
     1.5  }
     1.6  
     1.7 -void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
     1.8 -  assert(fl->count() == 0, "Precondition.");
     1.9 -  assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
    1.10 -         "Precondition");
    1.11 +// Used by par_get_chunk_of_blocks() for the chunks from the
    1.12 +// indexed_free_lists.  Looks for a chunk with size that is a multiple
    1.13 +// of "word_sz" and if found, splits it into "word_sz" chunks and add
    1.14 +// to the free list "fl".  "n" is the maximum number of chunks to
    1.15 +// be added to "fl".
    1.16 +bool CompactibleFreeListSpace:: par_get_chunk_of_blocks_IFL(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
    1.17  
    1.18    // We'll try all multiples of word_sz in the indexed set, starting with
    1.19    // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples,
    1.20 @@ -2817,11 +2819,15 @@
    1.21                          Mutex::_no_safepoint_check_flag);
    1.22          ssize_t births = _indexedFreeList[word_sz].split_births() + num;
    1.23          _indexedFreeList[word_sz].set_split_births(births);
    1.24 -        return;
    1.25 +        return true;
    1.26        }
    1.27      }
    1.28 +    return found;
    1.29    }
    1.30 -  // Otherwise, we'll split a block from the dictionary.
    1.31 +}
    1.32 +
    1.33 +FreeChunk* CompactibleFreeListSpace::get_n_way_chunk_to_split(size_t word_sz, size_t n) {
    1.34 +
    1.35    FreeChunk* fc = NULL;
    1.36    FreeChunk* rem_fc = NULL;
    1.37    size_t rem;
    1.38 @@ -2832,16 +2838,12 @@
    1.39        fc = dictionary()->get_chunk(MAX2(n * word_sz, _dictionary->min_size()),
    1.40                                    FreeBlockDictionary<FreeChunk>::atLeast);
    1.41        if (fc != NULL) {
    1.42 -        _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */);  // update _unallocated_blk
    1.43 -        dictionary()->dict_census_update(fc->size(),
    1.44 -                                       true /*split*/,
    1.45 -                                       false /*birth*/);
    1.46          break;
    1.47        } else {
    1.48          n--;
    1.49        }
    1.50      }
    1.51 -    if (fc == NULL) return;
    1.52 +    if (fc == NULL) return NULL;
    1.53      // Otherwise, split up that block.
    1.54      assert((ssize_t)n >= 1, "Control point invariant");
    1.55      assert(fc->is_free(), "Error: should be a free block");
    1.56 @@ -2863,10 +2865,14 @@
    1.57      // dictionary and return, leaving "fl" empty.
    1.58      if (n == 0) {
    1.59        returnChunkToDictionary(fc);
    1.60 -      assert(fl->count() == 0, "We never allocated any blocks");
    1.61 -      return;
    1.62 +      return NULL;
    1.63      }
    1.64  
    1.65 +    _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */);  // update _unallocated_blk
    1.66 +    dictionary()->dict_census_update(fc->size(),
    1.67 +                                     true /*split*/,
    1.68 +                                     false /*birth*/);
    1.69 +
    1.70      // First return the remainder, if any.
    1.71      // Note that we hold the lock until we decide if we're going to give
    1.72      // back the remainder to the dictionary, since a concurrent allocation
    1.73 @@ -2899,7 +2905,24 @@
    1.74      _indexedFreeList[rem].return_chunk_at_head(rem_fc);
    1.75      smallSplitBirth(rem);
    1.76    }
    1.77 -  assert((ssize_t)n > 0 && fc != NULL, "Consistency");
    1.78 +  assert(n * word_sz == fc->size(),
    1.79 +    err_msg("Chunk size " SIZE_FORMAT " is not exactly splittable by "
    1.80 +    SIZE_FORMAT " sized chunks of size " SIZE_FORMAT,
    1.81 +    fc->size(), n, word_sz));
    1.82 +  return fc;
    1.83 +}
    1.84 +
    1.85 +void CompactibleFreeListSpace:: par_get_chunk_of_blocks_dictionary(size_t word_sz, size_t targetted_number_of_chunks, AdaptiveFreeList<FreeChunk>* fl) {
    1.86 +
    1.87 +  FreeChunk* fc = get_n_way_chunk_to_split(word_sz, targetted_number_of_chunks);
    1.88 +
    1.89 +  if (fc == NULL) {
    1.90 +    return;
    1.91 +  }
    1.92 +
    1.93 +  size_t n = fc->size() / word_sz;
    1.94 +
    1.95 +  assert((ssize_t)n > 0, "Consistency");
    1.96    // Now do the splitting up.
    1.97    // Must do this in reverse order, so that anybody attempting to
    1.98    // access the main chunk sees it as a single free block until we
    1.99 @@ -2947,6 +2970,20 @@
   1.100    assert(fl->tail()->next() == NULL, "List invariant.");
   1.101  }
   1.102  
   1.103 +void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
   1.104 +  assert(fl->count() == 0, "Precondition.");
   1.105 +  assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
   1.106 +         "Precondition");
   1.107 +
   1.108 +  if (par_get_chunk_of_blocks_IFL(word_sz, n, fl)) {
   1.109 +    // Got it
   1.110 +    return;
   1.111 +  }
   1.112 +
   1.113 +  // Otherwise, we'll split a block from the dictionary.
   1.114 +  par_get_chunk_of_blocks_dictionary(word_sz, n, fl);
   1.115 +}
   1.116 +
   1.117  // Set up the space's par_seq_tasks structure for work claiming
   1.118  // for parallel rescan. See CMSParRemarkTask where this is currently used.
   1.119  // XXX Need to suitably abstract and generalize this and the next

mercurial