src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/gc_implementation/concurrentMarkSweep

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

Print this page
rev 5732 : [mq]: comments2


 390   // is itself a non-atomic computation. The normal use of
 391   // this is during a resize operation at the end of GC
 392   // and at that time you are guaranteed to get the
 393   // correct actual value. However, for instance, this is
 394   // also read completely asynchronously by the "perf-sampler"
 395   // that supports jvmstat, and you are apt to see the values
 396   // flicker in such cases.
 397   assert(_dictionary != NULL, "No _dictionary?");
 398   return (_dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())) +
 399           totalSizeInIndexedFreeLists() +
 400           _smallLinearAllocBlock._word_size) * HeapWordSize;
 401 }
 402 
 403 size_t CompactibleFreeListSpace::max_alloc_in_words() const {
 404   assert(_dictionary != NULL, "No _dictionary?");
 405   assert_locked();
 406   size_t res = _dictionary->max_chunk_size();
 407   res = MAX2(res, MIN2(_smallLinearAllocBlock._word_size,
 408                        (size_t) SmallForLinearAlloc - 1));
 409   // XXX the following could potentially be pretty slow;
 410   // should one, pesimally for the rare cases when res
 411   // caclulated above is less than IndexSetSize,
 412   // just return res calculated above? My reasoning was that
 413   // those cases will be so rare that the extra time spent doesn't
 414   // really matter....
 415   // Note: do not change the loop test i >= res + IndexSetStride
 416   // to i > res below, because i is unsigned and res may be zero.
 417   for (size_t i = IndexSetSize - 1; i >= res + IndexSetStride;
 418        i -= IndexSetStride) {
 419     if (_indexedFreeList[i].head() != NULL) {
 420       assert(_indexedFreeList[i].count() != 0, "Inconsistent FreeList");
 421       return i;
 422     }
 423   }
 424   return res;
 425 }
 426 
 427 void LinearAllocBlock::print_on(outputStream* st) const {
 428   st->print_cr(" LinearAllocBlock: ptr = " PTR_FORMAT ", word_size = " SIZE_FORMAT
 429             ", refillsize = " SIZE_FORMAT ", allocation_size_limit = " SIZE_FORMAT,
 430             _ptr, _word_size, _refillSize, _allocation_size_limit);
 431 }


 742   }                                                                             \
 743 }
 744 
 745 // (There are only two of these, rather than N, because the split is due
 746 // only to the introduction of the FilteringClosure, a local part of the
 747 // impl of this abstraction.)
 748 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(ExtendedOopClosure)
 749 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure)
 750 
 751 DirtyCardToOopClosure*
 752 CompactibleFreeListSpace::new_dcto_cl(ExtendedOopClosure* cl,
 753                                       CardTableModRefBS::PrecisionStyle precision,
 754                                       HeapWord* boundary) {
 755   return new FreeListSpace_DCTOC(this, _collector, cl, precision, boundary);
 756 }
 757 
 758 
 759 // Note on locking for the space iteration functions:
 760 // since the collector's iteration activities are concurrent with
 761 // allocation activities by mutators, absent a suitable mutual exclusion
 762 // mechanism the iterators may go awry. For instace a block being iterated
 763 // may suddenly be allocated or divided up and part of it allocated and
 764 // so on.
 765 
 766 // Apply the given closure to each block in the space.
 767 void CompactibleFreeListSpace::blk_iterate_careful(BlkClosureCareful* cl) {
 768   assert_lock_strong(freelistLock());
 769   HeapWord *cur, *limit;
 770   for (cur = bottom(), limit = end(); cur < limit;
 771        cur += cl->do_blk_careful(cur));
 772 }
 773 
 774 // Apply the given closure to each block in the space.
 775 void CompactibleFreeListSpace::blk_iterate(BlkClosure* cl) {
 776   assert_lock_strong(freelistLock());
 777   HeapWord *cur, *limit;
 778   for (cur = bottom(), limit = end(); cur < limit;
 779        cur += cl->do_blk(cur));
 780 }
 781 
 782 // Apply the given closure to each oop in the space.


2073   assert(blk->_word_size == 0 && blk->_ptr == NULL,
2074          "linear allocation block should be empty");
2075   FreeChunk* fc;
2076   if (blk->_refillSize < SmallForDictionary &&
2077       (fc = getChunkFromIndexedFreeList(blk->_refillSize)) != NULL) {
2078     // A linAB's strategy might be to use small sizes to reduce
2079     // fragmentation but still get the benefits of allocation from a
2080     // linAB.
2081   } else {
2082     fc = getChunkFromDictionary(blk->_refillSize);
2083   }
2084   if (fc != NULL) {
2085     blk->_ptr  = (HeapWord*)fc;
2086     blk->_word_size = fc->size();
2087     fc->dontCoalesce();   // to prevent sweeper from sweeping us up
2088   }
2089 }
2090 
2091 // Support for concurrent collection policy decisions.
2092 bool CompactibleFreeListSpace::should_concurrent_collect() const {
2093   // In the future we might want to add in frgamentation stats --
2094   // including erosion of the "mountain" into this decision as well.
2095   return !adaptive_freelists() && linearAllocationWouldFail();
2096 }
2097 
2098 // Support for compaction
2099 
2100 void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) {
2101   SCAN_AND_FORWARD(cp,end,block_is_obj,block_size);
2102   // prepare_for_compaction() uses the space between live objects
2103   // so that later phase can skip dead space quickly.  So verification
2104   // of the free lists doesn't work after.
2105 }
2106 
2107 #define obj_size(q) adjustObjectSize(oop(q)->size())
2108 #define adjust_obj_size(s) adjustObjectSize(s)
2109 
2110 void CompactibleFreeListSpace::adjust_pointers() {
2111   // In other versions of adjust_pointers(), a bail out
2112   // based on the amount of live data in the generation
2113   // (i.e., if 0, bail out) may be used.
2114   // Cannot test used() == 0 here because the free lists have already
2115   // been mangled by the compaction.
2116 
2117   SCAN_AND_ADJUST_POINTERS(adjust_obj_size);
2118   // See note about verification in prepare_for_compaction().
2119 }
2120 
2121 void CompactibleFreeListSpace::compact() {
2122   SCAN_AND_COMPACT(obj_size);
2123 }
2124 
2125 // fragmentation_metric = 1 - [sum of (fbs**2) / (sum of fbs)**2]
2126 // where fbs is free block sizes
2127 double CompactibleFreeListSpace::flsFrag() const {
2128   size_t itabFree = totalSizeInIndexedFreeLists();
2129   double frag = 0.0;
2130   size_t i;
2131 
2132   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2133     double sz  = i;
2134     frag      += _indexedFreeList[i].count() * (sz * sz);
2135   }
2136 
2137   double totFree = itabFree +
2138                    _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
2139   if (totFree > 0) {
2140     frag = ((frag + _dictionary->sum_of_squared_block_sizes()) /
2141             (totFree * totFree));
2142     frag = (double)1.0  - frag;
2143   } else {
2144     assert(frag == 0.0, "Follows from totFree == 0");
2145   }


2634   // mangle a just allocated object with a distinct pattern.
2635   debug_only(res->mangleAllocated(word_sz));
2636   return (HeapWord*)res;
2637 }
2638 
2639 // Get a chunk of blocks of the right size and update related
2640 // book-keeping stats
2641 void CFLS_LAB::get_from_global_pool(size_t word_sz, AdaptiveFreeList<FreeChunk>* fl) {
2642   // Get the #blocks we want to claim
2643   size_t n_blks = (size_t)_blocks_to_claim[word_sz].average();
2644   assert(n_blks > 0, "Error");
2645   assert(ResizePLAB || n_blks == OldPLABSize, "Error");
2646   // In some cases, when the application has a phase change,
2647   // there may be a sudden and sharp shift in the object survival
2648   // profile, and updating the counts at the end of a scavenge
2649   // may not be quick enough, giving rise to large scavenge pauses
2650   // during these phase changes. It is beneficial to detect such
2651   // changes on-the-fly during a scavenge and avoid such a phase-change
2652   // pothole. The following code is a heuristic attempt to do that.
2653   // It is protected by a product flag until we have gained
2654   // enough experience with this heuristic and fine-tuned its behaviour.
2655   // WARNING: This might increase fragmentation if we overreact to
2656   // small spikes, so some kind of historical smoothing based on
2657   // previous experience with the greater reactivity might be useful.
2658   // Lacking sufficient experience, CMSOldPLABResizeQuicker is disabled by
2659   // default.
2660   if (ResizeOldPLAB && CMSOldPLABResizeQuicker) {
2661     size_t multiple = _num_blocks[word_sz]/(CMSOldPLABToleranceFactor*CMSOldPLABNumRefills*n_blks);
2662     n_blks +=  CMSOldPLABReactivityFactor*multiple*n_blks;
2663     n_blks = MIN2(n_blks, CMSOldPLABMax);
2664   }
2665   assert(n_blks > 0, "Error");
2666   _cfls->par_get_chunk_of_blocks(word_sz, n_blks, fl);
2667   // Update stats table entry for this block size
2668   _num_blocks[word_sz] += fl->count();
2669 }
2670 
2671 void CFLS_LAB::compute_desired_plab_size() {
2672   for (size_t i =  CompactibleFreeListSpace::IndexSetStart;
2673        i < CompactibleFreeListSpace::IndexSetSize;
2674        i += CompactibleFreeListSpace::IndexSetStride) {




 390   // is itself a non-atomic computation. The normal use of
 391   // this is during a resize operation at the end of GC
 392   // and at that time you are guaranteed to get the
 393   // correct actual value. However, for instance, this is
 394   // also read completely asynchronously by the "perf-sampler"
 395   // that supports jvmstat, and you are apt to see the values
 396   // flicker in such cases.
 397   assert(_dictionary != NULL, "No _dictionary?");
 398   return (_dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())) +
 399           totalSizeInIndexedFreeLists() +
 400           _smallLinearAllocBlock._word_size) * HeapWordSize;
 401 }
 402 
 403 size_t CompactibleFreeListSpace::max_alloc_in_words() const {
 404   assert(_dictionary != NULL, "No _dictionary?");
 405   assert_locked();
 406   size_t res = _dictionary->max_chunk_size();
 407   res = MAX2(res, MIN2(_smallLinearAllocBlock._word_size,
 408                        (size_t) SmallForLinearAlloc - 1));
 409   // XXX the following could potentially be pretty slow;
 410   // should one, pessimistically for the rare cases when res
 411   // calculated above is less than IndexSetSize,
 412   // just return res calculated above? My reasoning was that
 413   // those cases will be so rare that the extra time spent doesn't
 414   // really matter....
 415   // Note: do not change the loop test i >= res + IndexSetStride
 416   // to i > res below, because i is unsigned and res may be zero.
 417   for (size_t i = IndexSetSize - 1; i >= res + IndexSetStride;
 418        i -= IndexSetStride) {
 419     if (_indexedFreeList[i].head() != NULL) {
 420       assert(_indexedFreeList[i].count() != 0, "Inconsistent FreeList");
 421       return i;
 422     }
 423   }
 424   return res;
 425 }
 426 
 427 void LinearAllocBlock::print_on(outputStream* st) const {
 428   st->print_cr(" LinearAllocBlock: ptr = " PTR_FORMAT ", word_size = " SIZE_FORMAT
 429             ", refillsize = " SIZE_FORMAT ", allocation_size_limit = " SIZE_FORMAT,
 430             _ptr, _word_size, _refillSize, _allocation_size_limit);
 431 }


 742   }                                                                             \
 743 }
 744 
 745 // (There are only two of these, rather than N, because the split is due
 746 // only to the introduction of the FilteringClosure, a local part of the
 747 // impl of this abstraction.)
 748 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(ExtendedOopClosure)
 749 FreeListSpace_DCTOC__walk_mem_region_with_cl_DEFN(FilteringClosure)
 750 
 751 DirtyCardToOopClosure*
 752 CompactibleFreeListSpace::new_dcto_cl(ExtendedOopClosure* cl,
 753                                       CardTableModRefBS::PrecisionStyle precision,
 754                                       HeapWord* boundary) {
 755   return new FreeListSpace_DCTOC(this, _collector, cl, precision, boundary);
 756 }
 757 
 758 
 759 // Note on locking for the space iteration functions:
 760 // since the collector's iteration activities are concurrent with
 761 // allocation activities by mutators, absent a suitable mutual exclusion
 762 // mechanism the iterators may go awry. For instance a block being iterated
 763 // may suddenly be allocated or divided up and part of it allocated and
 764 // so on.
 765 
 766 // Apply the given closure to each block in the space.
 767 void CompactibleFreeListSpace::blk_iterate_careful(BlkClosureCareful* cl) {
 768   assert_lock_strong(freelistLock());
 769   HeapWord *cur, *limit;
 770   for (cur = bottom(), limit = end(); cur < limit;
 771        cur += cl->do_blk_careful(cur));
 772 }
 773 
 774 // Apply the given closure to each block in the space.
 775 void CompactibleFreeListSpace::blk_iterate(BlkClosure* cl) {
 776   assert_lock_strong(freelistLock());
 777   HeapWord *cur, *limit;
 778   for (cur = bottom(), limit = end(); cur < limit;
 779        cur += cl->do_blk(cur));
 780 }
 781 
 782 // Apply the given closure to each oop in the space.


2073   assert(blk->_word_size == 0 && blk->_ptr == NULL,
2074          "linear allocation block should be empty");
2075   FreeChunk* fc;
2076   if (blk->_refillSize < SmallForDictionary &&
2077       (fc = getChunkFromIndexedFreeList(blk->_refillSize)) != NULL) {
2078     // A linAB's strategy might be to use small sizes to reduce
2079     // fragmentation but still get the benefits of allocation from a
2080     // linAB.
2081   } else {
2082     fc = getChunkFromDictionary(blk->_refillSize);
2083   }
2084   if (fc != NULL) {
2085     blk->_ptr  = (HeapWord*)fc;
2086     blk->_word_size = fc->size();
2087     fc->dontCoalesce();   // to prevent sweeper from sweeping us up
2088   }
2089 }
2090 
2091 // Support for concurrent collection policy decisions.
2092 bool CompactibleFreeListSpace::should_concurrent_collect() const {
2093   // In the future we might want to add in fragmentation stats --
2094   // including erosion of the "mountain" into this decision as well.
2095   return !adaptive_freelists() && linearAllocationWouldFail();
2096 }
2097 
2098 // Support for compaction
2099 
2100 void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) {
2101   SCAN_AND_FORWARD(cp,end,block_is_obj,block_size);
2102   // Prepare_for_compaction() uses the space between live objects
2103   // so that later phase can skip dead space quickly.  So verification
2104   // of the free lists doesn't work after.
2105 }
2106 
2107 #define obj_size(q) adjustObjectSize(oop(q)->size())
2108 #define adjust_obj_size(s) adjustObjectSize(s)
2109 
2110 void CompactibleFreeListSpace::adjust_pointers() {
2111   // In other versions of adjust_pointers(), a bail out
2112   // based on the amount of live data in the generation
2113   // (i.e., if 0, bail out) may be used.
2114   // Cannot test used() == 0 here because the free lists have already
2115   // been mangled by the compaction.
2116 
2117   SCAN_AND_ADJUST_POINTERS(adjust_obj_size);
2118   // See note about verification in prepare_for_compaction().
2119 }
2120 
2121 void CompactibleFreeListSpace::compact() {
2122   SCAN_AND_COMPACT(obj_size);
2123 }
2124 
2125 // Fragmentation metric = 1 - [sum of (fbs**2) / (sum of fbs)**2]
2126 // where fbs is free block sizes
2127 double CompactibleFreeListSpace::flsFrag() const {
2128   size_t itabFree = totalSizeInIndexedFreeLists();
2129   double frag = 0.0;
2130   size_t i;
2131 
2132   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2133     double sz  = i;
2134     frag      += _indexedFreeList[i].count() * (sz * sz);
2135   }
2136 
2137   double totFree = itabFree +
2138                    _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
2139   if (totFree > 0) {
2140     frag = ((frag + _dictionary->sum_of_squared_block_sizes()) /
2141             (totFree * totFree));
2142     frag = (double)1.0  - frag;
2143   } else {
2144     assert(frag == 0.0, "Follows from totFree == 0");
2145   }


2634   // mangle a just allocated object with a distinct pattern.
2635   debug_only(res->mangleAllocated(word_sz));
2636   return (HeapWord*)res;
2637 }
2638 
2639 // Get a chunk of blocks of the right size and update related
2640 // book-keeping stats
2641 void CFLS_LAB::get_from_global_pool(size_t word_sz, AdaptiveFreeList<FreeChunk>* fl) {
2642   // Get the #blocks we want to claim
2643   size_t n_blks = (size_t)_blocks_to_claim[word_sz].average();
2644   assert(n_blks > 0, "Error");
2645   assert(ResizePLAB || n_blks == OldPLABSize, "Error");
2646   // In some cases, when the application has a phase change,
2647   // there may be a sudden and sharp shift in the object survival
2648   // profile, and updating the counts at the end of a scavenge
2649   // may not be quick enough, giving rise to large scavenge pauses
2650   // during these phase changes. It is beneficial to detect such
2651   // changes on-the-fly during a scavenge and avoid such a phase-change
2652   // pothole. The following code is a heuristic attempt to do that.
2653   // It is protected by a product flag until we have gained
2654   // enough experience with this heuristic and fine-tuned its behavior.
2655   // WARNING: This might increase fragmentation if we overreact to
2656   // small spikes, so some kind of historical smoothing based on
2657   // previous experience with the greater reactivity might be useful.
2658   // Lacking sufficient experience, CMSOldPLABResizeQuicker is disabled by
2659   // default.
2660   if (ResizeOldPLAB && CMSOldPLABResizeQuicker) {
2661     size_t multiple = _num_blocks[word_sz]/(CMSOldPLABToleranceFactor*CMSOldPLABNumRefills*n_blks);
2662     n_blks +=  CMSOldPLABReactivityFactor*multiple*n_blks;
2663     n_blks = MIN2(n_blks, CMSOldPLABMax);
2664   }
2665   assert(n_blks > 0, "Error");
2666   _cfls->par_get_chunk_of_blocks(word_sz, n_blks, fl);
2667   // Update stats table entry for this block size
2668   _num_blocks[word_sz] += fl->count();
2669 }
2670 
2671 void CFLS_LAB::compute_desired_plab_size() {
2672   for (size_t i =  CompactibleFreeListSpace::IndexSetStart;
2673        i < CompactibleFreeListSpace::IndexSetSize;
2674        i += CompactibleFreeListSpace::IndexSetStride) {


src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File