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

Print this page
rev 6220 : [mq]: printffmt_size.gc.patch


 547 
 548 
 549 void CompactibleFreeListSpace::reportFreeListStatistics() const {
 550   assert_lock_strong(&_freelistLock);
 551   assert(PrintFLSStatistics != 0, "Reporting error");
 552   _dictionary->report_statistics();
 553   if (PrintFLSStatistics > 1) {
 554     reportIndexedFreeListStatistics();
 555     size_t total_size = totalSizeInIndexedFreeLists() +
 556                        _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
 557     gclog_or_tty->print(" free=" SIZE_FORMAT " frag=%1.4f\n", total_size, flsFrag());
 558   }
 559 }
 560 
 561 void CompactibleFreeListSpace::reportIndexedFreeListStatistics() const {
 562   assert_lock_strong(&_freelistLock);
 563   gclog_or_tty->print("Statistics for IndexedFreeLists:\n"
 564                       "--------------------------------\n");
 565   size_t total_size = totalSizeInIndexedFreeLists();
 566   size_t   free_blocks = numFreeBlocksInIndexedFreeLists();
 567   gclog_or_tty->print("Total Free Space: %d\n", total_size);
 568   gclog_or_tty->print("Max   Chunk Size: %d\n", maxChunkSizeInIndexedFreeLists());
 569   gclog_or_tty->print("Number of Blocks: %d\n", free_blocks);
 570   if (free_blocks != 0) {
 571     gclog_or_tty->print("Av.  Block  Size: %d\n", total_size/free_blocks);
 572   }
 573 }
 574 
 575 size_t CompactibleFreeListSpace::numFreeBlocksInIndexedFreeLists() const {
 576   size_t res = 0;
 577   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
 578     debug_only(
 579       ssize_t recount = 0;
 580       for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
 581          fc = fc->next()) {
 582         recount += 1;
 583       }
 584       assert(recount == _indexedFreeList[i].count(),
 585         "Incorrect count in list");
 586     )
 587     res += _indexedFreeList[i].count();
 588   }
 589   return res;
 590 }
 591 


2135                    _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
2136   if (totFree > 0) {
2137     frag = ((frag + _dictionary->sum_of_squared_block_sizes()) /
2138             (totFree * totFree));
2139     frag = (double)1.0  - frag;
2140   } else {
2141     assert(frag == 0.0, "Follows from totFree == 0");
2142   }
2143   return frag;
2144 }
2145 
2146 void CompactibleFreeListSpace::beginSweepFLCensus(
2147   float inter_sweep_current,
2148   float inter_sweep_estimate,
2149   float intra_sweep_estimate) {
2150   assert_locked();
2151   size_t i;
2152   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2153     AdaptiveFreeList<FreeChunk>* fl    = &_indexedFreeList[i];
2154     if (PrintFLSStatistics > 1) {
2155       gclog_or_tty->print("size[%d] : ", i);
2156     }
2157     fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate);
2158     fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent));
2159     fl->set_before_sweep(fl->count());
2160     fl->set_bfr_surp(fl->surplus());
2161   }
2162   _dictionary->begin_sweep_dict_census(CMSLargeCoalSurplusPercent,
2163                                     inter_sweep_current,
2164                                     inter_sweep_estimate,
2165                                     intra_sweep_estimate);
2166 }
2167 
2168 void CompactibleFreeListSpace::setFLSurplus() {
2169   assert_locked();
2170   size_t i;
2171   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2172     AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i];
2173     fl->set_surplus(fl->count() -
2174                     (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent));
2175   }


2666 }
2667 
2668 void CFLS_LAB::compute_desired_plab_size() {
2669   for (size_t i =  CompactibleFreeListSpace::IndexSetStart;
2670        i < CompactibleFreeListSpace::IndexSetSize;
2671        i += CompactibleFreeListSpace::IndexSetStride) {
2672     assert((_global_num_workers[i] == 0) == (_global_num_blocks[i] == 0),
2673            "Counter inconsistency");
2674     if (_global_num_workers[i] > 0) {
2675       // Need to smooth wrt historical average
2676       if (ResizeOldPLAB) {
2677         _blocks_to_claim[i].sample(
2678           MAX2((size_t)CMSOldPLABMin,
2679           MIN2((size_t)CMSOldPLABMax,
2680                _global_num_blocks[i]/(_global_num_workers[i]*CMSOldPLABNumRefills))));
2681       }
2682       // Reset counters for next round
2683       _global_num_workers[i] = 0;
2684       _global_num_blocks[i] = 0;
2685       if (PrintOldPLAB) {
2686         gclog_or_tty->print_cr("[%d]: %d", i, (size_t)_blocks_to_claim[i].average());

2687       }
2688     }
2689   }
2690 }
2691 
2692 // If this is changed in the future to allow parallel
2693 // access, one would need to take the FL locks and,
2694 // depending on how it is used, stagger access from
2695 // parallel threads to reduce contention.
2696 void CFLS_LAB::retire(int tid) {
2697   // We run this single threaded with the world stopped;
2698   // so no need for locks and such.
2699   NOT_PRODUCT(Thread* t = Thread::current();)
2700   assert(Thread::current()->is_VM_thread(), "Error");
2701   for (size_t i =  CompactibleFreeListSpace::IndexSetStart;
2702        i < CompactibleFreeListSpace::IndexSetSize;
2703        i += CompactibleFreeListSpace::IndexSetStride) {
2704     assert(_num_blocks[i] >= (size_t)_indexedFreeList[i].count(),
2705            "Can't retire more than what we obtained");
2706     if (_num_blocks[i] > 0) {
2707       size_t num_retire =  _indexedFreeList[i].count();
2708       assert(_num_blocks[i] > num_retire, "Should have used at least one");
2709       {
2710         // MutexLockerEx x(_cfls->_indexedFreeListParLocks[i],
2711         //                Mutex::_no_safepoint_check_flag);
2712 
2713         // Update globals stats for num_blocks used
2714         _global_num_blocks[i] += (_num_blocks[i] - num_retire);
2715         _global_num_workers[i]++;
2716         assert(_global_num_workers[i] <= ParallelGCThreads, "Too big");
2717         if (num_retire > 0) {
2718           _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]);
2719           // Reset this list.
2720           _indexedFreeList[i] = AdaptiveFreeList<FreeChunk>();
2721           _indexedFreeList[i].set_size(i);
2722         }
2723       }
2724       if (PrintOldPLAB) {
2725         gclog_or_tty->print_cr("%d[%d]: %d/%d/%d",
2726                                tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average());
2727       }
2728       // Reset stats for next round
2729       _num_blocks[i]         = 0;
2730     }
2731   }
2732 }
2733 
2734 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
2735   assert(fl->count() == 0, "Precondition.");
2736   assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
2737          "Precondition");
2738 
2739   // We'll try all multiples of word_sz in the indexed set, starting with
2740   // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples,
2741   // then try getting a big chunk and splitting it.
2742   {
2743     bool found;
2744     int  k;
2745     size_t cur_sz;




 547 
 548 
 549 void CompactibleFreeListSpace::reportFreeListStatistics() const {
 550   assert_lock_strong(&_freelistLock);
 551   assert(PrintFLSStatistics != 0, "Reporting error");
 552   _dictionary->report_statistics();
 553   if (PrintFLSStatistics > 1) {
 554     reportIndexedFreeListStatistics();
 555     size_t total_size = totalSizeInIndexedFreeLists() +
 556                        _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
 557     gclog_or_tty->print(" free=" SIZE_FORMAT " frag=%1.4f\n", total_size, flsFrag());
 558   }
 559 }
 560 
 561 void CompactibleFreeListSpace::reportIndexedFreeListStatistics() const {
 562   assert_lock_strong(&_freelistLock);
 563   gclog_or_tty->print("Statistics for IndexedFreeLists:\n"
 564                       "--------------------------------\n");
 565   size_t total_size = totalSizeInIndexedFreeLists();
 566   size_t   free_blocks = numFreeBlocksInIndexedFreeLists();
 567   gclog_or_tty->print("Total Free Space: " SIZE_FORMAT "\n", total_size);
 568   gclog_or_tty->print("Max   Chunk Size: " SIZE_FORMAT "\n", maxChunkSizeInIndexedFreeLists());
 569   gclog_or_tty->print("Number of Blocks: " SIZE_FORMAT "\n", free_blocks);
 570   if (free_blocks != 0) {
 571     gclog_or_tty->print("Av.  Block  Size: " SIZE_FORMAT "\n", total_size/free_blocks);
 572   }
 573 }
 574 
 575 size_t CompactibleFreeListSpace::numFreeBlocksInIndexedFreeLists() const {
 576   size_t res = 0;
 577   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
 578     debug_only(
 579       ssize_t recount = 0;
 580       for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
 581          fc = fc->next()) {
 582         recount += 1;
 583       }
 584       assert(recount == _indexedFreeList[i].count(),
 585         "Incorrect count in list");
 586     )
 587     res += _indexedFreeList[i].count();
 588   }
 589   return res;
 590 }
 591 


2135                    _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
2136   if (totFree > 0) {
2137     frag = ((frag + _dictionary->sum_of_squared_block_sizes()) /
2138             (totFree * totFree));
2139     frag = (double)1.0  - frag;
2140   } else {
2141     assert(frag == 0.0, "Follows from totFree == 0");
2142   }
2143   return frag;
2144 }
2145 
2146 void CompactibleFreeListSpace::beginSweepFLCensus(
2147   float inter_sweep_current,
2148   float inter_sweep_estimate,
2149   float intra_sweep_estimate) {
2150   assert_locked();
2151   size_t i;
2152   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2153     AdaptiveFreeList<FreeChunk>* fl    = &_indexedFreeList[i];
2154     if (PrintFLSStatistics > 1) {
2155       gclog_or_tty->print("size[" SIZE_FORMAT "] : ", i);
2156     }
2157     fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate);
2158     fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent));
2159     fl->set_before_sweep(fl->count());
2160     fl->set_bfr_surp(fl->surplus());
2161   }
2162   _dictionary->begin_sweep_dict_census(CMSLargeCoalSurplusPercent,
2163                                     inter_sweep_current,
2164                                     inter_sweep_estimate,
2165                                     intra_sweep_estimate);
2166 }
2167 
2168 void CompactibleFreeListSpace::setFLSurplus() {
2169   assert_locked();
2170   size_t i;
2171   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
2172     AdaptiveFreeList<FreeChunk> *fl = &_indexedFreeList[i];
2173     fl->set_surplus(fl->count() -
2174                     (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent));
2175   }


2666 }
2667 
2668 void CFLS_LAB::compute_desired_plab_size() {
2669   for (size_t i =  CompactibleFreeListSpace::IndexSetStart;
2670        i < CompactibleFreeListSpace::IndexSetSize;
2671        i += CompactibleFreeListSpace::IndexSetStride) {
2672     assert((_global_num_workers[i] == 0) == (_global_num_blocks[i] == 0),
2673            "Counter inconsistency");
2674     if (_global_num_workers[i] > 0) {
2675       // Need to smooth wrt historical average
2676       if (ResizeOldPLAB) {
2677         _blocks_to_claim[i].sample(
2678           MAX2((size_t)CMSOldPLABMin,
2679           MIN2((size_t)CMSOldPLABMax,
2680                _global_num_blocks[i]/(_global_num_workers[i]*CMSOldPLABNumRefills))));
2681       }
2682       // Reset counters for next round
2683       _global_num_workers[i] = 0;
2684       _global_num_blocks[i] = 0;
2685       if (PrintOldPLAB) {
2686         gclog_or_tty->print_cr("[" SIZE_FORMAT "]: " SIZE_FORMAT,
2687                                i, (size_t)_blocks_to_claim[i].average());
2688       }
2689     }
2690   }
2691 }
2692 
2693 // If this is changed in the future to allow parallel
2694 // access, one would need to take the FL locks and,
2695 // depending on how it is used, stagger access from
2696 // parallel threads to reduce contention.
2697 void CFLS_LAB::retire(int tid) {
2698   // We run this single threaded with the world stopped;
2699   // so no need for locks and such.
2700   NOT_PRODUCT(Thread* t = Thread::current();)
2701   assert(Thread::current()->is_VM_thread(), "Error");
2702   for (size_t i =  CompactibleFreeListSpace::IndexSetStart;
2703        i < CompactibleFreeListSpace::IndexSetSize;
2704        i += CompactibleFreeListSpace::IndexSetStride) {
2705     assert(_num_blocks[i] >= (size_t)_indexedFreeList[i].count(),
2706            "Can't retire more than what we obtained");
2707     if (_num_blocks[i] > 0) {
2708       size_t num_retire =  _indexedFreeList[i].count();
2709       assert(_num_blocks[i] > num_retire, "Should have used at least one");
2710       {
2711         // MutexLockerEx x(_cfls->_indexedFreeListParLocks[i],
2712         //                Mutex::_no_safepoint_check_flag);
2713 
2714         // Update globals stats for num_blocks used
2715         _global_num_blocks[i] += (_num_blocks[i] - num_retire);
2716         _global_num_workers[i]++;
2717         assert(_global_num_workers[i] <= ParallelGCThreads, "Too big");
2718         if (num_retire > 0) {
2719           _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]);
2720           // Reset this list.
2721           _indexedFreeList[i] = AdaptiveFreeList<FreeChunk>();
2722           _indexedFreeList[i].set_size(i);
2723         }
2724       }
2725       if (PrintOldPLAB) {
2726         gclog_or_tty->print_cr("%d[" SIZE_FORMAT "]: " SIZE_FORMAT "/" SIZE_FORMAT "/" SIZE_FORMAT,
2727                                tid, i, num_retire, _num_blocks[i], (size_t)_blocks_to_claim[i].average());
2728       }
2729       // Reset stats for next round
2730       _num_blocks[i]         = 0;
2731     }
2732   }
2733 }
2734 
2735 void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, AdaptiveFreeList<FreeChunk>* fl) {
2736   assert(fl->count() == 0, "Precondition.");
2737   assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
2738          "Precondition");
2739 
2740   // We'll try all multiples of word_sz in the indexed set, starting with
2741   // word_sz itself and, if CMSSplitIndexedFreeListBlocks, try larger multiples,
2742   // then try getting a big chunk and splitting it.
2743   {
2744     bool found;
2745     int  k;
2746     size_t cur_sz;