Tue, 15 May 2012 00:56:06 +0200
7158457: division by zero in adaptiveweightedaverage
Summary: Add ceiling to AdaptiveWeightedAverage
Reviewed-by: ysr, iveresov
src/share/vm/gc_implementation/shared/gcUtil.cpp | file | annotate | diff | comparison | revisions | |
src/share/vm/gc_implementation/shared/gcUtil.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/gc_implementation/shared/gcUtil.cpp Fri May 11 14:54:35 2012 -0700 1.2 +++ b/src/share/vm/gc_implementation/shared/gcUtil.cpp Tue May 15 00:56:06 2012 +0200 1.3 @@ -31,9 +31,15 @@ 1.4 float average) { 1.5 // We smooth the samples by not using weight() directly until we've 1.6 // had enough data to make it meaningful. We'd like the first weight 1.7 - // used to be 1, the second to be 1/2, etc until we have 100/weight 1.8 - // samples. 1.9 - unsigned count_weight = 100/count(); 1.10 + // used to be 1, the second to be 1/2, etc until we have 1.11 + // OLD_THRESHOLD/weight samples. 1.12 + unsigned count_weight = 0; 1.13 + 1.14 + // Avoid division by zero if the counter wraps (7158457) 1.15 + if (!is_old()) { 1.16 + count_weight = OLD_THRESHOLD/count(); 1.17 + } 1.18 + 1.19 unsigned adaptive_weight = (MAX2(weight(), count_weight)); 1.20 1.21 float new_avg = exp_avg(average, new_sample, adaptive_weight); 1.22 @@ -43,8 +49,6 @@ 1.23 1.24 void AdaptiveWeightedAverage::sample(float new_sample) { 1.25 increment_count(); 1.26 - assert(count() != 0, 1.27 - "Wraparound -- history would be incorrectly discarded"); 1.28 1.29 // Compute the new weighted average 1.30 float new_avg = compute_adaptive_average(new_sample, average());
2.1 --- a/src/share/vm/gc_implementation/shared/gcUtil.hpp Fri May 11 14:54:35 2012 -0700 2.2 +++ b/src/share/vm/gc_implementation/shared/gcUtil.hpp Tue May 15 00:56:06 2012 +0200 2.3 @@ -50,11 +50,20 @@ 2.4 unsigned _weight; // The weight used to smooth the averages 2.5 // A higher weight favors the most 2.6 // recent data. 2.7 + bool _is_old; // Has enough historical data 2.8 + 2.9 + const static unsigned OLD_THRESHOLD = 100; 2.10 2.11 protected: 2.12 float _last_sample; // The last value sampled. 2.13 2.14 - void increment_count() { _sample_count++; } 2.15 + void increment_count() { 2.16 + _sample_count++; 2.17 + if (!_is_old && _sample_count > OLD_THRESHOLD) { 2.18 + _is_old = true; 2.19 + } 2.20 + } 2.21 + 2.22 void set_average(float avg) { _average = avg; } 2.23 2.24 // Helper function, computes an adaptive weighted average 2.25 @@ -64,13 +73,15 @@ 2.26 public: 2.27 // Input weight must be between 0 and 100 2.28 AdaptiveWeightedAverage(unsigned weight, float avg = 0.0) : 2.29 - _average(avg), _sample_count(0), _weight(weight), _last_sample(0.0) { 2.30 + _average(avg), _sample_count(0), _weight(weight), _last_sample(0.0), 2.31 + _is_old(false) { 2.32 } 2.33 2.34 void clear() { 2.35 _average = 0; 2.36 _sample_count = 0; 2.37 _last_sample = 0; 2.38 + _is_old = false; 2.39 } 2.40 2.41 // Useful for modifying static structures after startup. 2.42 @@ -84,7 +95,8 @@ 2.43 float average() const { return _average; } 2.44 unsigned weight() const { return _weight; } 2.45 unsigned count() const { return _sample_count; } 2.46 - float last_sample() const { return _last_sample; } 2.47 + float last_sample() const { return _last_sample; } 2.48 + bool is_old() const { return _is_old; } 2.49 2.50 // Update data with a new sample. 2.51 void sample(float new_sample);