< prev index next >

src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp

Print this page




 136 
 137   restart_with(non_taxable, tax);
 138 
 139   log_info(gc, ergo)("Pacer for Traversal. Expected Live: " SIZE_FORMAT "M, Free: " SIZE_FORMAT
 140                      "M, Non-Taxable: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx",
 141                      live / M, free / M, non_taxable / M, tax);
 142 }
 143 
 144 /*
 145  * In idle phase, we have to pace the application to let control thread react with GC start.
 146  *
 147  * Here, we have rendezvous with concurrent thread that adds up the budget as it acknowledges
 148  * it had seen recent allocations. It will naturally pace the allocations if control thread is
 149  * not catching up. To bootstrap this feedback cycle, we need to start with some initial budget
 150  * for applications to allocate at.
 151  */
 152 
 153 void ShenandoahPacer::setup_for_idle() {
 154   assert(ShenandoahPacing, "Only be here when pacing is enabled");
 155 
 156   size_t initial = _heap->max_capacity() / 100 * ShenandoahPacingIdleSlack;
 157   double tax = 1;
 158 
 159   restart_with(initial, tax);
 160 
 161   log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx",
 162                      initial / M, tax);
 163 }
 164 
 165 size_t ShenandoahPacer::update_and_get_progress_history() {
 166   if (_progress == -1) {
 167     // First initialization, report some prior
 168     Atomic::store((intptr_t)PACING_PROGRESS_ZERO, &_progress);
 169     return (size_t) (_heap->max_capacity() * 0.1);
 170   } else {
 171     // Record history, and reply historical data
 172     _progress_history->add(_progress);
 173     Atomic::store((intptr_t)PACING_PROGRESS_ZERO, &_progress);
 174     return (size_t) (_progress_history->avg() * HeapWordSize);
 175   }
 176 }
 177 
 178 void ShenandoahPacer::restart_with(size_t non_taxable_bytes, double tax_rate) {
 179   size_t initial = (size_t)(non_taxable_bytes * tax_rate) >> LogHeapWordSize;
 180   STATIC_ASSERT(sizeof(size_t) <= sizeof(intptr_t));
 181   Atomic::xchg((intptr_t)initial, &_budget);
 182   Atomic::store(tax_rate, &_tax_rate);
 183   Atomic::inc(&_epoch);
 184 }
 185 
 186 bool ShenandoahPacer::claim_for_alloc(size_t words, bool force) {
 187   assert(ShenandoahPacing, "Only be here when pacing is enabled");
 188 
 189   intptr_t tax = MAX2<intptr_t>(1, words * Atomic::load(&_tax_rate));




 136 
 137   restart_with(non_taxable, tax);
 138 
 139   log_info(gc, ergo)("Pacer for Traversal. Expected Live: " SIZE_FORMAT "M, Free: " SIZE_FORMAT
 140                      "M, Non-Taxable: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx",
 141                      live / M, free / M, non_taxable / M, tax);
 142 }
 143 
 144 /*
 145  * In idle phase, we have to pace the application to let control thread react with GC start.
 146  *
 147  * Here, we have rendezvous with concurrent thread that adds up the budget as it acknowledges
 148  * it had seen recent allocations. It will naturally pace the allocations if control thread is
 149  * not catching up. To bootstrap this feedback cycle, we need to start with some initial budget
 150  * for applications to allocate at.
 151  */
 152 
 153 void ShenandoahPacer::setup_for_idle() {
 154   assert(ShenandoahPacing, "Only be here when pacing is enabled");
 155 
 156   size_t initial = _heap->capacity() * ShenandoahPacingIdleSlack / 100;
 157   double tax = 1;
 158 
 159   restart_with(initial, tax);
 160 
 161   log_info(gc, ergo)("Pacer for Idle. Initial: " SIZE_FORMAT "M, Alloc Tax Rate: %.1fx",
 162                      initial / M, tax);
 163 }
 164 
 165 size_t ShenandoahPacer::update_and_get_progress_history() {
 166   if (_progress == -1) {
 167     // First initialization, report some prior
 168     Atomic::store((intptr_t)PACING_PROGRESS_ZERO, &_progress);
 169     return (size_t) (_heap->capacity() * 0.1);
 170   } else {
 171     // Record history, and reply historical data
 172     _progress_history->add(_progress);
 173     Atomic::store((intptr_t)PACING_PROGRESS_ZERO, &_progress);
 174     return (size_t) (_progress_history->avg() * HeapWordSize);
 175   }
 176 }
 177 
 178 void ShenandoahPacer::restart_with(size_t non_taxable_bytes, double tax_rate) {
 179   size_t initial = (size_t)(non_taxable_bytes * tax_rate) >> LogHeapWordSize;
 180   STATIC_ASSERT(sizeof(size_t) <= sizeof(intptr_t));
 181   Atomic::xchg((intptr_t)initial, &_budget);
 182   Atomic::store(tax_rate, &_tax_rate);
 183   Atomic::inc(&_epoch);
 184 }
 185 
 186 bool ShenandoahPacer::claim_for_alloc(size_t words, bool force) {
 187   assert(ShenandoahPacing, "Only be here when pacing is enabled");
 188 
 189   intptr_t tax = MAX2<intptr_t>(1, words * Atomic::load(&_tax_rate));


< prev index next >