src/share/vm/gc_implementation/shared/gcUtil.hpp

Thu, 20 Sep 2012 09:52:56 -0700

author
johnc
date
Thu, 20 Sep 2012 09:52:56 -0700
changeset 4067
b2ef234911c9
parent 3900
d2a62e0f25eb
child 4153
b9a9ed0f8eeb
permissions
-rw-r--r--

7190666: G1: assert(_unused == 0) failed: Inconsistency in PLAB stats
Summary: Reset the fields in ParGCAllocBuffer, that are used for accumulating values for the ResizePLAB sensors in PLABStats, to zero after flushing the values to the PLABStats fields. Flush PLABStats values only when retiring the final allocation buffers prior to disposing of a G1ParScanThreadState object, rather than when retiring every allocation buffer.
Reviewed-by: jwilhelm, jmasa, ysr

duke@435 1 /*
stefank@2314 2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_GCUTIL_HPP
stefank@2314 26 #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCUTIL_HPP
stefank@2314 27
stefank@2314 28 #include "memory/allocation.hpp"
stefank@2314 29 #include "runtime/timer.hpp"
stefank@2314 30 #include "utilities/debug.hpp"
stefank@2314 31 #include "utilities/globalDefinitions.hpp"
stefank@2314 32 #include "utilities/ostream.hpp"
stefank@2314 33
duke@435 34 // Catch-all file for utility classes
duke@435 35
duke@435 36 // A weighted average maintains a running, weighted average
duke@435 37 // of some float value (templates would be handy here if we
duke@435 38 // need different types).
duke@435 39 //
duke@435 40 // The average is adaptive in that we smooth it for the
duke@435 41 // initial samples; we don't use the weight until we have
duke@435 42 // enough samples for it to be meaningful.
duke@435 43 //
duke@435 44 // This serves as our best estimate of a future unknown.
duke@435 45 //
zgu@3900 46 class AdaptiveWeightedAverage : public CHeapObj<mtGC> {
duke@435 47 private:
duke@435 48 float _average; // The last computed average
duke@435 49 unsigned _sample_count; // How often we've sampled this average
duke@435 50 unsigned _weight; // The weight used to smooth the averages
duke@435 51 // A higher weight favors the most
duke@435 52 // recent data.
mikael@3763 53 bool _is_old; // Has enough historical data
mikael@3763 54
mikael@3763 55 const static unsigned OLD_THRESHOLD = 100;
duke@435 56
duke@435 57 protected:
duke@435 58 float _last_sample; // The last value sampled.
duke@435 59
mikael@3763 60 void increment_count() {
mikael@3763 61 _sample_count++;
mikael@3763 62 if (!_is_old && _sample_count > OLD_THRESHOLD) {
mikael@3763 63 _is_old = true;
mikael@3763 64 }
mikael@3763 65 }
mikael@3763 66
duke@435 67 void set_average(float avg) { _average = avg; }
duke@435 68
duke@435 69 // Helper function, computes an adaptive weighted average
duke@435 70 // given a sample and the last average
duke@435 71 float compute_adaptive_average(float new_sample, float average);
duke@435 72
duke@435 73 public:
duke@435 74 // Input weight must be between 0 and 100
ysr@1580 75 AdaptiveWeightedAverage(unsigned weight, float avg = 0.0) :
mikael@3763 76 _average(avg), _sample_count(0), _weight(weight), _last_sample(0.0),
mikael@3763 77 _is_old(false) {
duke@435 78 }
duke@435 79
iveresov@703 80 void clear() {
iveresov@703 81 _average = 0;
iveresov@703 82 _sample_count = 0;
iveresov@703 83 _last_sample = 0;
mikael@3763 84 _is_old = false;
iveresov@703 85 }
iveresov@703 86
ysr@1580 87 // Useful for modifying static structures after startup.
ysr@1580 88 void modify(size_t avg, unsigned wt, bool force = false) {
ysr@1580 89 assert(force, "Are you sure you want to call this?");
ysr@1580 90 _average = (float)avg;
ysr@1580 91 _weight = wt;
ysr@1580 92 }
ysr@1580 93
duke@435 94 // Accessors
duke@435 95 float average() const { return _average; }
duke@435 96 unsigned weight() const { return _weight; }
duke@435 97 unsigned count() const { return _sample_count; }
mikael@3763 98 float last_sample() const { return _last_sample; }
mikael@3763 99 bool is_old() const { return _is_old; }
duke@435 100
duke@435 101 // Update data with a new sample.
duke@435 102 void sample(float new_sample);
duke@435 103
duke@435 104 static inline float exp_avg(float avg, float sample,
duke@435 105 unsigned int weight) {
duke@435 106 assert(0 <= weight && weight <= 100, "weight must be a percent");
duke@435 107 return (100.0F - weight) * avg / 100.0F + weight * sample / 100.0F;
duke@435 108 }
duke@435 109 static inline size_t exp_avg(size_t avg, size_t sample,
duke@435 110 unsigned int weight) {
duke@435 111 // Convert to float and back to avoid integer overflow.
duke@435 112 return (size_t)exp_avg((float)avg, (float)sample, weight);
duke@435 113 }
ysr@1580 114
ysr@1580 115 // Printing
ysr@1580 116 void print_on(outputStream* st) const;
ysr@1580 117 void print() const;
duke@435 118 };
duke@435 119
duke@435 120
duke@435 121 // A weighted average that includes a deviation from the average,
duke@435 122 // some multiple of which is added to the average.
duke@435 123 //
duke@435 124 // This serves as our best estimate of an upper bound on a future
duke@435 125 // unknown.
duke@435 126 class AdaptivePaddedAverage : public AdaptiveWeightedAverage {
duke@435 127 private:
duke@435 128 float _padded_avg; // The last computed padded average
duke@435 129 float _deviation; // Running deviation from the average
duke@435 130 unsigned _padding; // A multiple which, added to the average,
duke@435 131 // gives us an upper bound guess.
duke@435 132
duke@435 133 protected:
duke@435 134 void set_padded_average(float avg) { _padded_avg = avg; }
duke@435 135 void set_deviation(float dev) { _deviation = dev; }
duke@435 136
duke@435 137 public:
duke@435 138 AdaptivePaddedAverage() :
duke@435 139 AdaptiveWeightedAverage(0),
duke@435 140 _padded_avg(0.0), _deviation(0.0), _padding(0) {}
duke@435 141
duke@435 142 AdaptivePaddedAverage(unsigned weight, unsigned padding) :
duke@435 143 AdaptiveWeightedAverage(weight),
duke@435 144 _padded_avg(0.0), _deviation(0.0), _padding(padding) {}
duke@435 145
duke@435 146 // Placement support
duke@435 147 void* operator new(size_t ignored, void* p) { return p; }
duke@435 148 // Allocator
zgu@3900 149 void* operator new(size_t size) { return CHeapObj<mtGC>::operator new(size); }
duke@435 150
duke@435 151 // Accessor
duke@435 152 float padded_average() const { return _padded_avg; }
duke@435 153 float deviation() const { return _deviation; }
duke@435 154 unsigned padding() const { return _padding; }
duke@435 155
iveresov@703 156 void clear() {
iveresov@703 157 AdaptiveWeightedAverage::clear();
iveresov@703 158 _padded_avg = 0;
iveresov@703 159 _deviation = 0;
iveresov@703 160 }
iveresov@703 161
duke@435 162 // Override
duke@435 163 void sample(float new_sample);
ysr@1580 164
ysr@1580 165 // Printing
ysr@1580 166 void print_on(outputStream* st) const;
ysr@1580 167 void print() const;
duke@435 168 };
duke@435 169
duke@435 170 // A weighted average that includes a deviation from the average,
duke@435 171 // some multiple of which is added to the average.
duke@435 172 //
duke@435 173 // This serves as our best estimate of an upper bound on a future
duke@435 174 // unknown.
duke@435 175 // A special sort of padded average: it doesn't update deviations
duke@435 176 // if the sample is zero. The average is allowed to change. We're
duke@435 177 // preventing the zero samples from drastically changing our padded
duke@435 178 // average.
duke@435 179 class AdaptivePaddedNoZeroDevAverage : public AdaptivePaddedAverage {
duke@435 180 public:
duke@435 181 AdaptivePaddedNoZeroDevAverage(unsigned weight, unsigned padding) :
duke@435 182 AdaptivePaddedAverage(weight, padding) {}
duke@435 183 // Override
duke@435 184 void sample(float new_sample);
ysr@1580 185
ysr@1580 186 // Printing
ysr@1580 187 void print_on(outputStream* st) const;
ysr@1580 188 void print() const;
duke@435 189 };
ysr@1580 190
duke@435 191 // Use a least squares fit to a set of data to generate a linear
duke@435 192 // equation.
duke@435 193 // y = intercept + slope * x
duke@435 194
zgu@3900 195 class LinearLeastSquareFit : public CHeapObj<mtGC> {
duke@435 196 double _sum_x; // sum of all independent data points x
duke@435 197 double _sum_x_squared; // sum of all independent data points x**2
duke@435 198 double _sum_y; // sum of all dependent data points y
duke@435 199 double _sum_xy; // sum of all x * y.
duke@435 200 double _intercept; // constant term
duke@435 201 double _slope; // slope
duke@435 202 // The weighted averages are not currently used but perhaps should
duke@435 203 // be used to get decaying averages.
duke@435 204 AdaptiveWeightedAverage _mean_x; // weighted mean of independent variable
duke@435 205 AdaptiveWeightedAverage _mean_y; // weighted mean of dependent variable
duke@435 206
duke@435 207 public:
duke@435 208 LinearLeastSquareFit(unsigned weight);
duke@435 209 void update(double x, double y);
duke@435 210 double y(double x);
duke@435 211 double slope() { return _slope; }
duke@435 212 // Methods to decide if a change in the dependent variable will
duke@435 213 // achive a desired goal. Note that these methods are not
duke@435 214 // complementary and both are needed.
duke@435 215 bool decrement_will_decrease();
duke@435 216 bool increment_will_decrease();
duke@435 217 };
duke@435 218
duke@435 219 class GCPauseTimer : StackObj {
duke@435 220 elapsedTimer* _timer;
duke@435 221 public:
duke@435 222 GCPauseTimer(elapsedTimer* timer) {
duke@435 223 _timer = timer;
duke@435 224 _timer->stop();
duke@435 225 }
duke@435 226 ~GCPauseTimer() {
duke@435 227 _timer->start();
duke@435 228 }
duke@435 229 };
stefank@2314 230
stefank@2314 231 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GCUTIL_HPP

mercurial