7158457: division by zero in adaptiveweightedaverage

Tue, 15 May 2012 00:56:06 +0200

author
mikael
date
Tue, 15 May 2012 00:56:06 +0200
changeset 3763
78a1b285cda8
parent 3757
56d1af561395
child 3764
33e366609904

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);

mercurial