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

changeset 3220
c08412904149
parent 2958
1e3493ac2d11
child 3264
5a5ed80bea5b
     1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Sun Oct 23 23:06:06 2011 -0700
     1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Tue Oct 25 20:15:41 2011 -0700
     1.3 @@ -62,7 +62,7 @@
     1.4    MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment;
     1.5  
     1.6    assert(IndexSetStart == 0 && IndexSetStride == 0, "already set");
     1.7 -  IndexSetStart  = MinObjAlignment;
     1.8 +  IndexSetStart  = (int) MinChunkSize;
     1.9    IndexSetStride = MinObjAlignment;
    1.10  }
    1.11  
    1.12 @@ -138,7 +138,7 @@
    1.13    } else {
    1.14      _fitStrategy = FreeBlockStrategyNone;
    1.15    }
    1.16 -  checkFreeListConsistency();
    1.17 +  check_free_list_consistency();
    1.18  
    1.19    // Initialize locks for parallel case.
    1.20  
    1.21 @@ -1358,17 +1358,29 @@
    1.22    ShouldNotReachHere();
    1.23  }
    1.24  
    1.25 -bool CompactibleFreeListSpace::verifyChunkInIndexedFreeLists(FreeChunk* fc)
    1.26 -  const {
    1.27 +bool CompactibleFreeListSpace::verifyChunkInIndexedFreeLists(FreeChunk* fc) const {
    1.28    assert(fc->size() < IndexSetSize, "Size of chunk is too large");
    1.29    return _indexedFreeList[fc->size()].verifyChunkInFreeLists(fc);
    1.30  }
    1.31  
    1.32 +bool CompactibleFreeListSpace::verify_chunk_is_linear_alloc_block(FreeChunk* fc) const {
    1.33 +  assert((_smallLinearAllocBlock._ptr != (HeapWord*)fc) ||
    1.34 +         (_smallLinearAllocBlock._word_size == fc->size()),
    1.35 +         "Linear allocation block shows incorrect size");
    1.36 +  return ((_smallLinearAllocBlock._ptr == (HeapWord*)fc) &&
    1.37 +          (_smallLinearAllocBlock._word_size == fc->size()));
    1.38 +}
    1.39 +
    1.40 +// Check if the purported free chunk is present either as a linear
    1.41 +// allocation block, the size-indexed table of (smaller) free blocks,
    1.42 +// or the larger free blocks kept in the binary tree dictionary.
    1.43  bool CompactibleFreeListSpace::verifyChunkInFreeLists(FreeChunk* fc) const {
    1.44 -  if (fc->size() >= IndexSetSize) {
    1.45 +  if (verify_chunk_is_linear_alloc_block(fc)) {
    1.46 +    return true;
    1.47 +  } else if (fc->size() < IndexSetSize) {
    1.48 +    return verifyChunkInIndexedFreeLists(fc);
    1.49 +  } else {
    1.50      return dictionary()->verifyChunkInFreeLists(fc);
    1.51 -  } else {
    1.52 -    return verifyChunkInIndexedFreeLists(fc);
    1.53    }
    1.54  }
    1.55  
    1.56 @@ -2495,7 +2507,8 @@
    1.57    FreeChunk* tail =  _indexedFreeList[size].tail();
    1.58    size_t    num = _indexedFreeList[size].count();
    1.59    size_t      n = 0;
    1.60 -  guarantee((size % 2 == 0) || fc == NULL, "Odd slots should be empty");
    1.61 +  guarantee(((size >= MinChunkSize) && (size % IndexSetStride == 0)) || fc == NULL,
    1.62 +            "Slot should have been empty");
    1.63    for (; fc != NULL; fc = fc->next(), n++) {
    1.64      guarantee(fc->size() == size, "Size inconsistency");
    1.65      guarantee(fc->isFree(), "!free?");
    1.66 @@ -2506,14 +2519,14 @@
    1.67  }
    1.68  
    1.69  #ifndef PRODUCT
    1.70 -void CompactibleFreeListSpace::checkFreeListConsistency() const {
    1.71 +void CompactibleFreeListSpace::check_free_list_consistency() const {
    1.72    assert(_dictionary->minSize() <= IndexSetSize,
    1.73      "Some sizes can't be allocated without recourse to"
    1.74      " linear allocation buffers");
    1.75    assert(MIN_TREE_CHUNK_SIZE*HeapWordSize == sizeof(TreeChunk),
    1.76      "else MIN_TREE_CHUNK_SIZE is wrong");
    1.77 -  assert((IndexSetStride == 2 && IndexSetStart == 2) ||
    1.78 -         (IndexSetStride == 1 && IndexSetStart == 1), "just checking");
    1.79 +  assert((IndexSetStride == 2 && IndexSetStart == 4) ||                   // 32-bit
    1.80 +         (IndexSetStride == 1 && IndexSetStart == 3), "just checking");   // 64-bit
    1.81    assert((IndexSetStride != 2) || (MinChunkSize % 2 == 0),
    1.82        "Some for-loops may be incorrectly initialized");
    1.83    assert((IndexSetStride != 2) || (IndexSetSize % 2 == 1),
    1.84 @@ -2688,33 +2701,27 @@
    1.85    }
    1.86  }
    1.87  
    1.88 +// If this is changed in the future to allow parallel
    1.89 +// access, one would need to take the FL locks and,
    1.90 +// depending on how it is used, stagger access from
    1.91 +// parallel threads to reduce contention.
    1.92  void CFLS_LAB::retire(int tid) {
    1.93    // We run this single threaded with the world stopped;
    1.94    // so no need for locks and such.
    1.95 -#define CFLS_LAB_PARALLEL_ACCESS 0
    1.96    NOT_PRODUCT(Thread* t = Thread::current();)
    1.97    assert(Thread::current()->is_VM_thread(), "Error");
    1.98 -  assert(CompactibleFreeListSpace::IndexSetStart == CompactibleFreeListSpace::IndexSetStride,
    1.99 -         "Will access to uninitialized slot below");
   1.100 -#if CFLS_LAB_PARALLEL_ACCESS
   1.101 -  for (size_t i = CompactibleFreeListSpace::IndexSetSize - 1;
   1.102 -       i > 0;
   1.103 -       i -= CompactibleFreeListSpace::IndexSetStride) {
   1.104 -#else // CFLS_LAB_PARALLEL_ACCESS
   1.105    for (size_t i =  CompactibleFreeListSpace::IndexSetStart;
   1.106         i < CompactibleFreeListSpace::IndexSetSize;
   1.107         i += CompactibleFreeListSpace::IndexSetStride) {
   1.108 -#endif // !CFLS_LAB_PARALLEL_ACCESS
   1.109      assert(_num_blocks[i] >= (size_t)_indexedFreeList[i].count(),
   1.110             "Can't retire more than what we obtained");
   1.111      if (_num_blocks[i] > 0) {
   1.112        size_t num_retire =  _indexedFreeList[i].count();
   1.113        assert(_num_blocks[i] > num_retire, "Should have used at least one");
   1.114        {
   1.115 -#if CFLS_LAB_PARALLEL_ACCESS
   1.116 -        MutexLockerEx x(_cfls->_indexedFreeListParLocks[i],
   1.117 -                        Mutex::_no_safepoint_check_flag);
   1.118 -#endif // CFLS_LAB_PARALLEL_ACCESS
   1.119 +        // MutexLockerEx x(_cfls->_indexedFreeListParLocks[i],
   1.120 +        //                Mutex::_no_safepoint_check_flag);
   1.121 +
   1.122          // Update globals stats for num_blocks used
   1.123          _global_num_blocks[i] += (_num_blocks[i] - num_retire);
   1.124          _global_num_workers[i]++;

mercurial