am e5426c99: Fix histogram memory issues.
* commit 'e5426c9995d28bcb19391d8dbf0ad70606cf1770':
Fix histogram memory issues.
diff --git a/runtime/base/histogram-inl.h b/runtime/base/histogram-inl.h
index 1a63cf4..0345266 100644
--- a/runtime/base/histogram-inl.h
+++ b/runtime/base/histogram-inl.h
@@ -29,7 +29,7 @@
namespace art {
template <class Value> inline void Histogram<Value>::AddValue(Value value) {
- CHECK_GE(value, 0.0);
+ CHECK_GE(value, static_cast<Value>(0));
if (value >= max_) {
Value new_max = ((value + 1) / bucket_width_ + 1) * bucket_width_;
DCHECK_GT(new_max, max_);
@@ -37,91 +37,90 @@
}
BucketiseValue(value);
- new_values_added_ = true;
}
template <class Value>
-inline Histogram<Value>::Histogram(const std::string name)
+inline Histogram<Value>::Histogram(const char* name, Value initial_bucket_width,
+ size_t max_buckets)
: kAdjust(1000),
- kBucketWidth(5),
- kInitialBucketCount(10),
- bucket_width_(kBucketWidth),
- bucket_count_(kInitialBucketCount) {
- name_ = name;
+ kInitialBucketCount(8),
+ name_(name),
+ max_buckets_(max_buckets),
+ bucket_width_(initial_bucket_width) {
Reset();
}
template <class Value>
inline void Histogram<Value>::GrowBuckets(Value new_max) {
while (max_ < new_max) {
+ // If we have reached the maximum number of buckets, merge buckets together.
+ if (frequency_.size() >= max_buckets_) {
+ CHECK(IsAligned<2>(frequency_.size()));
+ // We double the width of each bucket to reduce the number of buckets by a factor of 2.
+ bucket_width_ *= 2;
+ const size_t limit = frequency_.size() / 2;
+ // Merge the frequencies by adding each adjacent two together.
+ for (size_t i = 0; i < limit; ++i) {
+ frequency_[i] = frequency_[i * 2] + frequency_[i * 2 + 1];
+ }
+ // Remove frequencies in the second half of the array which were added to the first half.
+ while (frequency_.size() > limit) {
+ frequency_.pop_back();
+ }
+ }
max_ += bucket_width_;
- ranges_.push_back(max_);
frequency_.push_back(0);
- bucket_count_++;
}
}
-template <class Value> inline size_t Histogram<Value>::FindBucket(Value val) {
+template <class Value> inline size_t Histogram<Value>::FindBucket(Value val) const {
// Since this is only a linear histogram, bucket index can be found simply with
// dividing the value by the bucket width.
DCHECK_GE(val, min_);
DCHECK_LE(val, max_);
- size_t bucket_idx = static_cast<size_t>(static_cast<double>(val - min_) / bucket_width_);
+ const size_t bucket_idx = static_cast<size_t>((val - min_) / bucket_width_);
DCHECK_GE(bucket_idx, 0ul);
- DCHECK_LE(bucket_idx, bucket_count_);
+ DCHECK_LE(bucket_idx, GetBucketCount());
return bucket_idx;
}
template <class Value>
-inline void Histogram<Value>::BucketiseValue(Value value) {
- CHECK_LT(value, max_);
- sum_ += value;
- sum_of_squares_ += value * value;
- size_t bucket_idx = FindBucket(value);
- sample_size_++;
- if (value > max_value_added_) {
- max_value_added_ = value;
- }
- if (value < min_value_added_) {
- min_value_added_ = value;
- }
- frequency_[bucket_idx]++;
+inline void Histogram<Value>::BucketiseValue(Value val) {
+ CHECK_LT(val, max_);
+ sum_ += val;
+ sum_of_squares_ += val * val;
+ ++sample_size_;
+ ++frequency_[FindBucket(val)];
+ max_value_added_ = std::max(val, max_value_added_);
+ min_value_added_ = std::min(val, min_value_added_);
}
template <class Value> inline void Histogram<Value>::Initialize() {
- DCHECK_GT(bucket_count_, 0ul);
- size_t idx = 0;
- for (; idx < bucket_count_; idx++) {
- ranges_.push_back(min_ + static_cast<Value>(idx) * (bucket_width_));
+ for (size_t idx = 0; idx < kInitialBucketCount; idx++) {
frequency_.push_back(0);
}
// Cumulative frequency and ranges has a length of 1 over frequency.
- ranges_.push_back(min_ + idx * bucket_width_);
- max_ = bucket_width_ * bucket_count_;
+ max_ = bucket_width_ * GetBucketCount();
+}
+
+template <class Value> inline size_t Histogram<Value>::GetBucketCount() const {
+ return frequency_.size();
}
template <class Value> inline void Histogram<Value>::Reset() {
- bucket_width_ = kBucketWidth;
- bucket_count_ = kInitialBucketCount;
- max_ = bucket_width_ * bucket_count_;
sum_of_squares_ = 0;
sample_size_ = 0;
min_ = 0;
sum_ = 0;
min_value_added_ = std::numeric_limits<Value>::max();
max_value_added_ = std::numeric_limits<Value>::min();
- new_values_added_ = false;
- ranges_.clear();
frequency_.clear();
- cumulative_freq_.clear();
- cumulative_perc_.clear();
Initialize();
}
-template <class Value> inline void Histogram<Value>::BuildRanges() {
- for (size_t idx = 0; idx < bucket_count_; ++idx) {
- ranges_.push_back(min_ + idx * bucket_width_);
- }
+template <class Value> inline Value Histogram<Value>::GetRange(size_t bucket_idx) const {
+ DCHECK_LE(bucket_idx, GetBucketCount());
+ return min_ + bucket_idx * bucket_width_;
}
template <class Value> inline double Histogram<Value>::Mean() const {
@@ -143,25 +142,21 @@
}
template <class Value>
-inline void Histogram<Value>::PrintBins(std::ostream &os) {
+inline void Histogram<Value>::PrintBins(std::ostream& os, const CumulativeData& data) const {
DCHECK_GT(sample_size_, 0ull);
- DCHECK(!new_values_added_);
- size_t bin_idx = 0;
- while (bin_idx < cumulative_freq_.size()) {
- if (bin_idx > 0 &&
- cumulative_perc_[bin_idx] == cumulative_perc_[bin_idx - 1]) {
+ for (size_t bin_idx = 0; bin_idx < data.freq_.size(); ++bin_idx) {
+ if (bin_idx > 0 && data.perc_[bin_idx] == data.perc_[bin_idx - 1]) {
bin_idx++;
continue;
}
- os << ranges_[bin_idx] << ": " << cumulative_freq_[bin_idx] << "\t"
- << cumulative_perc_[bin_idx] * 100.0 << "%\n";
- bin_idx++;
+ os << GetRange(bin_idx) << ": " << data.freq_[bin_idx] << "\t"
+ << data.perc_[bin_idx] * 100.0 << "%\n";
}
}
template <class Value>
-inline void Histogram<Value>::PrintConfidenceIntervals(std::ostream &os,
- double interval) const {
+inline void Histogram<Value>::PrintConfidenceIntervals(std::ostream &os, double interval,
+ const CumulativeData& data) const {
DCHECK_GT(interval, 0);
DCHECK_LT(interval, 1.0);
@@ -169,69 +164,51 @@
double per_1 = per_0 + interval;
os << Name() << ":\t";
TimeUnit unit = GetAppropriateTimeUnit(Mean() * kAdjust);
- os << (interval * 100) << "% C.I. "
- << FormatDuration(Percentile(per_0) * kAdjust, unit);
- os << "-" << FormatDuration(Percentile(per_1) * kAdjust, unit) << " ";
+ os << (interval * 100) << "% C.I. " << FormatDuration(Percentile(per_0, data) * kAdjust, unit);
+ os << "-" << FormatDuration(Percentile(per_1, data) * kAdjust, unit) << " ";
os << "Avg: " << FormatDuration(Mean() * kAdjust, unit) << " Max: ";
os << FormatDuration(Max() * kAdjust, unit) << "\n";
}
-template <class Value> inline void Histogram<Value>::BuildCDF() {
- DCHECK_EQ(cumulative_freq_.size(), 0ull);
- DCHECK_EQ(cumulative_perc_.size(), 0ull);
+template <class Value> inline void Histogram<Value>::CreateHistogram(CumulativeData& out_data) {
+ DCHECK_GT(sample_size_, 0ull);
+ out_data.freq_.clear();
+ out_data.perc_.clear();
uint64_t accumulated = 0;
-
- cumulative_freq_.push_back(accumulated);
- cumulative_perc_.push_back(0.0);
+ out_data.freq_.push_back(accumulated);
+ out_data.perc_.push_back(0.0);
for (size_t idx = 0; idx < frequency_.size(); idx++) {
accumulated += frequency_[idx];
- cumulative_freq_.push_back(accumulated);
- cumulative_perc_.push_back(static_cast<double>(accumulated) /
- static_cast<double>(sample_size_));
+ out_data.freq_.push_back(accumulated);
+ out_data.perc_.push_back(static_cast<double>(accumulated) / static_cast<double>(sample_size_));
}
- DCHECK_EQ(*(cumulative_freq_.end() - 1), sample_size_);
- DCHECK_EQ(*(cumulative_perc_.end() - 1), 1.0);
-}
-
-template <class Value> inline void Histogram<Value>::CreateHistogram() {
- DCHECK_GT(sample_size_, 0ull);
-
- // Create a histogram only if new values are added.
- if (!new_values_added_)
- return;
-
- // Reset cumulative values in case this is not the first time creating histogram.
- cumulative_freq_.clear();
- cumulative_perc_.clear();
- BuildCDF();
- new_values_added_ = false;
+ DCHECK_EQ(out_data.freq_.back(), sample_size_);
+ DCHECK_LE(std::abs(out_data.perc_.back() - 1.0), 0.001);
}
template <class Value>
-inline double Histogram<Value>::Percentile(double per) const {
- DCHECK_GT(cumulative_perc_.size(), 0ull);
- size_t idx, upper_idx = 0, lower_idx = 0;
- for (idx = 0; idx < cumulative_perc_.size(); idx++) {
- if (per <= cumulative_perc_[idx]) {
+inline double Histogram<Value>::Percentile(double per, const CumulativeData& data) const {
+ DCHECK_GT(data.perc_.size(), 0ull);
+ size_t upper_idx = 0, lower_idx = 0;
+ for (size_t idx = 0; idx < data.perc_.size(); idx++) {
+ if (per <= data.perc_[idx]) {
upper_idx = idx;
break;
}
- if (per >= cumulative_perc_[idx] && idx != 0 &&
- cumulative_perc_[idx] != cumulative_perc_[idx - 1]) {
+ if (per >= data.perc_[idx] && idx != 0 && data.perc_[idx] != data.perc_[idx - 1]) {
lower_idx = idx;
}
}
- double upper_value = static_cast<double>(ranges_[upper_idx]);
- double lower_value = static_cast<double>(ranges_[lower_idx]);
-
- double lower_perc = cumulative_perc_[lower_idx];
- double upper_perc = cumulative_perc_[upper_idx];
-
+ const double lower_perc = data.perc_[lower_idx];
+ const double lower_value = static_cast<double>(GetRange(lower_idx));
if (per == lower_perc) {
return lower_value;
}
+
+ const double upper_perc = data.perc_[upper_idx];
+ const double upper_value = static_cast<double>(GetRange(upper_idx));
if (per == upper_perc) {
return upper_value;
}
diff --git a/runtime/base/histogram.h b/runtime/base/histogram.h
index 33a1e65..f508af9 100644
--- a/runtime/base/histogram.h
+++ b/runtime/base/histogram.h
@@ -31,19 +31,33 @@
template <class Value> class Histogram {
const double kAdjust;
- const Value kBucketWidth;
const size_t kInitialBucketCount;
public:
- explicit Histogram(std::string);
+ class CumulativeData {
+ friend class Histogram<Value>;
+ std::vector<uint64_t> freq_;
+ std::vector<double> perc_;
+ };
+
+ Histogram(const char* name, Value initial_bucket_width, size_t max_buckets = 100);
void AddValue(Value);
- void CreateHistogram();
+ // Builds the cumulative distribution function from the frequency data.
+ // Accumulative summation of frequencies.
+ // cumulative_freq[i] = sum(frequency[j] : 0 < j < i )
+ // Accumulative summation of percentiles; which is the frequency / SampleSize
+ // cumulative_perc[i] = sum(frequency[j] / SampleSize : 0 < j < i )
+ void CreateHistogram(CumulativeData& data);
+ // Reset the cumulative values, next time CreateHistogram is called it will recreate the cache.
void Reset();
double Mean() const;
double Variance() const;
- double Percentile(double) const;
- void PrintConfidenceIntervals(std::ostream &, double) const;
- void PrintBins(std::ostream &);
+ double Percentile(double per, const CumulativeData& data) const;
+ void PrintConfidenceIntervals(std::ostream& os, double interval,
+ const CumulativeData& data) const;
+ void PrintBins(std::ostream& os, const CumulativeData& data) const;
+ Value GetRange(size_t bucket_idx) const;
+ size_t GetBucketCount() const;
uint64_t SampleSize() const {
return sample_size_;
@@ -61,49 +75,33 @@
return max_value_added_;
}
- const std::string &Name() const {
+ const std::string& Name() const {
return name_;
}
-
private:
- void BuildRanges();
void Initialize();
- size_t FindBucket(Value);
- void BucketiseValue(Value);
- // Builds the cumulative distribution function from the frequency data.
- // Must be called before using the percentile function.
- void BuildCDF();
+ size_t FindBucket(Value val) const;
+ void BucketiseValue(Value val);
// Add more buckets to the histogram to fill in a new value that exceeded
// the max_read_value_.
- void GrowBuckets(Value);
- bool new_values_added_;
+ void GrowBuckets(Value val);
std::string name_;
+ // Maximum number of buckets.
+ const size_t max_buckets_;
// Number of samples placed in histogram.
- uint64_t sample_size_;
+ size_t sample_size_;
// Width of the bucket range. The lower the value is the more accurate
- // histogram percentiles are.
+ // histogram percentiles are. Grows adaptively when we hit max buckets.
Value bucket_width_;
- // Number of bucket to have in the histogram. this value will increase
- // to accommodate for big values that don't fit in initial bucket ranges.
- size_t bucket_count_;
- // Represents the ranges of the histograms. Has SampleSize() + 1 elements
- // e.g. 0,5,10,15 represents ranges 0-5, 5-10, 10-15
- std::vector<Value> ranges_;
- // How many occurrences of values fall within a corresponding range that is
- // saved in the ranges_ vector.
- std::vector<uint64_t> frequency_;
- // Accumulative summation of frequencies.
- // cumulative_freq_[i] = sum(cumulative_freq_[j] : 0 < j < i )
- std::vector<uint64_t> cumulative_freq_;
- // Accumulative summation of percentiles; which is the frequency / SampleSize
- // cumulative_freq_[i] = sum(cumulative_freq_[j] : 0 < j < i )
- std::vector<double> cumulative_perc_;
+ // How many occurrences of values fall within a bucket at index i where i covers the range
+ // starting at min_ + i * bucket_width_ with size bucket_size_.
+ std::vector<uint32_t> frequency_;
// Summation of all the elements inputed by the user.
Value sum_;
- // Maximum value that can fit in the histogram, grows adaptively.
- Value min_;
// Minimum value that can fit in the histogram. Fixed to zero for now.
+ Value min_;
+ // Maximum value that can fit in the histogram, grows adaptively.
Value max_;
// Summation of the values entered. Used to calculate variance.
Value sum_of_squares_;
diff --git a/runtime/base/histogram_test.cc b/runtime/base/histogram_test.cc
index 218c022..534440c 100644
--- a/runtime/base/histogram_test.cc
+++ b/runtime/base/histogram_test.cc
@@ -23,7 +23,7 @@
namespace art {
// Simple usage:
-// Histogram *hist = new Histogram("SimplePercentiles");
+// Histogram *hist(new Histogram("SimplePercentiles"));
// Percentile PerValue
// hist->AddValue(121);
// hist->AddValue(132);
@@ -34,7 +34,7 @@
// PerValue = hist->PercentileVal(0.50); finds the 50th percentile(median).
TEST(Histtest, MeanTest) {
- UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("MeanTest"));
+ UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("MeanTest", 5));
double mean;
for (size_t Idx = 0; Idx < 90; Idx++) {
@@ -52,20 +52,20 @@
}
TEST(Histtest, VarianceTest) {
- UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("VarianceTest"));
+ UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("VarianceTest", 5));
double variance;
hist->AddValue(9);
hist->AddValue(17);
hist->AddValue(28);
hist->AddValue(28);
- hist->CreateHistogram();
variance = hist->Variance();
EXPECT_EQ(64.25, variance);
}
TEST(Histtest, Percentile) {
- UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("Percentile"));
+ UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("Percentile", 5));
+ Histogram<uint64_t>::CumulativeData data;
double PerValue;
@@ -85,13 +85,14 @@
hist->AddValue(145);
hist->AddValue(155);
- hist->CreateHistogram();
- PerValue = hist->Percentile(0.50);
+ hist->CreateHistogram(data);
+ PerValue = hist->Percentile(0.50, data);
EXPECT_EQ(875, static_cast<int>(PerValue * 10));
}
TEST(Histtest, UpdateRange) {
- UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("UpdateRange"));
+ UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("UpdateRange", 5));
+ Histogram<uint64_t>::CumulativeData data;
double PerValue;
@@ -116,14 +117,13 @@
hist->AddValue(200);
hist->AddValue(205);
hist->AddValue(212);
- hist->CreateHistogram();
- PerValue = hist->Percentile(0.50);
+ hist->CreateHistogram(data);
+ PerValue = hist->Percentile(0.50, data);
std::string text;
std::stringstream stream;
- std::string expected =
- "UpdateRange:\t99% C.I. 15us-212us Avg: 126.380us Max: 212us\n";
- hist->PrintConfidenceIntervals(stream, 0.99);
+ std::string expected("UpdateRange:\t99% C.I. 15us-212us Avg: 126.380us Max: 212us\n");
+ hist->PrintConfidenceIntervals(stream, 0.99, data);
EXPECT_EQ(expected, stream.str());
EXPECT_GE(PerValue, 132);
@@ -131,7 +131,8 @@
}
TEST(Histtest, Reset) {
- UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("Reset"));
+ UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("Reset", 5));
+ Histogram<uint64_t>::CumulativeData data;
double PerValue;
hist->AddValue(0);
@@ -159,14 +160,13 @@
hist->AddValue(200);
hist->AddValue(205);
hist->AddValue(212);
- hist->CreateHistogram();
- PerValue = hist->Percentile(0.50);
+ hist->CreateHistogram(data);
+ PerValue = hist->Percentile(0.50, data);
std::string text;
std::stringstream stream;
- std::string expected =
- "Reset:\t99% C.I. 15us-212us Avg: 126.380us Max: 212us\n";
- hist->PrintConfidenceIntervals(stream, 0.99);
+ std::string expected("Reset:\t99% C.I. 15us-212us Avg: 126.380us Max: 212us\n");
+ hist->PrintConfidenceIntervals(stream, 0.99, data);
EXPECT_EQ(expected, stream.str());
EXPECT_GE(PerValue, 132);
@@ -174,7 +174,8 @@
}
TEST(Histtest, MultipleCreateHist) {
- UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("MultipleCreateHist"));
+ UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("MultipleCreateHist", 5));
+ Histogram<uint64_t>::CumulativeData data;
double PerValue;
hist->AddValue(15);
@@ -184,7 +185,7 @@
hist->AddValue(68);
hist->AddValue(75);
hist->AddValue(93);
- hist->CreateHistogram();
+ hist->CreateHistogram(data);
hist->AddValue(110);
hist->AddValue(121);
hist->AddValue(132);
@@ -193,19 +194,18 @@
hist->AddValue(155);
hist->AddValue(163);
hist->AddValue(168);
- hist->CreateHistogram();
+ hist->CreateHistogram(data);
hist->AddValue(175);
hist->AddValue(182);
hist->AddValue(193);
hist->AddValue(200);
hist->AddValue(205);
hist->AddValue(212);
- hist->CreateHistogram();
- PerValue = hist->Percentile(0.50);
+ hist->CreateHistogram(data);
+ PerValue = hist->Percentile(0.50, data);
std::stringstream stream;
- std::string expected =
- "MultipleCreateHist:\t99% C.I. 15us-212us Avg: 126.380us Max: 212us\n";
- hist->PrintConfidenceIntervals(stream, 0.99);
+ std::string expected("MultipleCreateHist:\t99% C.I. 15us-212us Avg: 126.380us Max: 212us\n");
+ hist->PrintConfidenceIntervals(stream, 0.99, data);
EXPECT_EQ(expected, stream.str());
EXPECT_GE(PerValue, 132);
@@ -213,18 +213,20 @@
}
TEST(Histtest, SingleValue) {
- UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("SingleValue"));
+ UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("SingleValue", 5));
+ Histogram<uint64_t>::CumulativeData data;
hist->AddValue(1);
- hist->CreateHistogram();
+ hist->CreateHistogram(data);
std::stringstream stream;
std::string expected = "SingleValue:\t99% C.I. 1us-1us Avg: 1us Max: 1us\n";
- hist->PrintConfidenceIntervals(stream, 0.99);
+ hist->PrintConfidenceIntervals(stream, 0.99, data);
EXPECT_EQ(expected, stream.str());
}
TEST(Histtest, CappingPercentiles) {
- UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("CappingPercentiles"));
+ UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("CappingPercentiles", 5));
+ Histogram<uint64_t>::CumulativeData data;
double per_995;
double per_005;
@@ -232,8 +234,8 @@
for (uint64_t idx = 0ull; idx < 150ull; idx++) {
hist->AddValue(0);
}
- hist->CreateHistogram();
- per_995 = hist->Percentile(0.995);
+ hist->CreateHistogram(data);
+ per_995 = hist->Percentile(0.995, data);
EXPECT_EQ(per_995, 0);
hist->Reset();
for (size_t idx = 0; idx < 200; idx++) {
@@ -241,15 +243,16 @@
hist->AddValue(val);
}
}
- hist->CreateHistogram();
- per_005 = hist->Percentile(0.005);
- per_995 = hist->Percentile(0.995);
+ hist->CreateHistogram(data);
+ per_005 = hist->Percentile(0.005, data);
+ per_995 = hist->Percentile(0.995, data);
EXPECT_EQ(1, per_005);
EXPECT_EQ(4, per_995);
}
TEST(Histtest, SpikyValues) {
- UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("SpikyValues"));
+ UniquePtr<Histogram<uint64_t> > hist(new Histogram<uint64_t>("SpikyValues", 5, 4096));
+ Histogram<uint64_t>::CumulativeData data;
for (uint64_t idx = 0ull; idx < 30ull; idx++) {
for (uint64_t idx_inner = 0ull; idx_inner < 5ull; idx_inner++) {
@@ -257,11 +260,10 @@
}
}
hist->AddValue(10000);
- hist->CreateHistogram();
+ hist->CreateHistogram(data);
std::stringstream stream;
- std::string expected =
- "SpikyValues:\t99% C.I. 0.089us-2541.825us Avg: 95.033us Max: 10000us\n";
- hist->PrintConfidenceIntervals(stream, 0.99);
+ std::string expected = "SpikyValues:\t99% C.I. 0.089us-2541.825us Avg: 95.033us Max: 10000us\n";
+ hist->PrintConfidenceIntervals(stream, 0.99, data);
EXPECT_EQ(expected, stream.str());
}
diff --git a/runtime/base/timing_logger.cc b/runtime/base/timing_logger.cc
index dfb0220..e2d2d4c 100644
--- a/runtime/base/timing_logger.cc
+++ b/runtime/base/timing_logger.cc
@@ -79,7 +79,8 @@
MutexLock mu(Thread::Current(), lock_);
const std::vector<std::pair<uint64_t, const char*> >& splits = logger.GetSplits();
typedef std::vector<std::pair<uint64_t, const char*> >::const_iterator It;
- if (kIsDebugBuild && splits.size() != histograms_.size()) {
+ // The first time this is run, the histograms array will be empty.
+ if (kIsDebugBuild && !histograms_.empty() && splits.size() != histograms_.size()) {
LOG(ERROR) << "Mismatch in splits.";
typedef std::vector<Histogram<uint64_t> *>::const_iterator It2;
It it = splits.begin();
@@ -111,24 +112,24 @@
void CumulativeLogger::AddPair(const std::string &label, uint64_t delta_time) {
// Convert delta time to microseconds so that we don't overflow our counters.
delta_time /= kAdjust;
- if (index_ >= histograms_.size()) {
- Histogram<uint64_t> *tmp_hist = new Histogram<uint64_t>(label);
- tmp_hist->AddValue(delta_time);
- histograms_.push_back(tmp_hist);
- } else {
- histograms_[index_]->AddValue(delta_time);
- DCHECK_EQ(label, histograms_[index_]->Name());
+ if (histograms_.size() <= index_) {
+ histograms_.push_back(new Histogram<uint64_t>(label.c_str(), 50));
+ DCHECK_GT(histograms_.size(), index_);
}
- index_++;
+ histograms_[index_]->AddValue(delta_time);
+ DCHECK_EQ(label, histograms_[index_]->Name());
+ ++index_;
}
void CumulativeLogger::DumpHistogram(std::ostream &os) {
os << "Start Dumping histograms for " << iterations_ << " iterations"
<< " for " << name_ << "\n";
for (size_t Idx = 0; Idx < histograms_.size(); Idx++) {
- Histogram<uint64_t> &hist = *(histograms_[Idx]);
- hist.CreateHistogram();
- hist.PrintConfidenceIntervals(os, 0.99);
+ Histogram<uint64_t>::CumulativeData cumulative_data;
+ histograms_[Idx]->CreateHistogram(cumulative_data);
+ histograms_[Idx]->PrintConfidenceIntervals(os, 0.99, cumulative_data);
+ // Reset cumulative values to save memory. We don't expect DumpHistogram to be called often, so
+ // it is not performance critical.
}
os << "Done Dumping histograms \n";
}
diff --git a/runtime/gc/space/dlmalloc_space.cc b/runtime/gc/space/dlmalloc_space.cc
index de4917f..a42e880 100644
--- a/runtime/gc/space/dlmalloc_space.cc
+++ b/runtime/gc/space/dlmalloc_space.cc
@@ -131,8 +131,8 @@
size_t bitmap_index = bitmap_index_++;
static const uintptr_t kGcCardSize = static_cast<uintptr_t>(accounting::CardTable::kCardSize);
- CHECK_EQ(reinterpret_cast<uintptr_t>(mem_map->Begin()) % kGcCardSize, 0U);
- CHECK_EQ(reinterpret_cast<uintptr_t>(mem_map->End()) % kGcCardSize, 0U);
+ CHECK(IsAligned<kGcCardSize>(reinterpret_cast<uintptr_t>(mem_map->Begin())));
+ CHECK(IsAligned<kGcCardSize>(reinterpret_cast<uintptr_t>(mem_map->End())));
live_bitmap_.reset(accounting::SpaceBitmap::Create(
StringPrintf("allocspace %s live-bitmap %d", name.c_str(), static_cast<int>(bitmap_index)),
Begin(), Capacity()));
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 4862c0a..8ff7025 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -56,7 +56,7 @@
std::vector<std::string> arg_vector;
- std::string dex2oat = GetAndroidRoot();
+ std::string dex2oat(GetAndroidRoot());
dex2oat += (kIsDebugBuild ? "/bin/dex2oatd" : "/bin/dex2oat");
arg_vector.push_back(dex2oat);