OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Histogram is an object that aggregates statistics, and can summarize them in | 5 // Histogram is an object that aggregates statistics, and can summarize them in |
6 // various forms, including ASCII graphical, HTML, and numerically (as a | 6 // various forms, including ASCII graphical, HTML, and numerically (as a |
7 // vector of numbers corresponding to each of the aggregating buckets). | 7 // vector of numbers corresponding to each of the aggregating buckets). |
8 // See header file for details and examples. | 8 // See header file for details and examples. |
9 | 9 |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 HistogramBase* Histogram::Factory::Build() { | 149 HistogramBase* Histogram::Factory::Build() { |
150 // Import histograms from known persistent storage. Histograms could have | 150 // Import histograms from known persistent storage. Histograms could have |
151 // been added by other processes and they must be fetched and recognized | 151 // been added by other processes and they must be fetched and recognized |
152 // locally in order to be found by FindHistograms() below. If the persistent | 152 // locally in order to be found by FindHistograms() below. If the persistent |
153 // memory segment is not shared between processes, this call does nothing. | 153 // memory segment is not shared between processes, this call does nothing. |
154 ImportPersistentHistograms(); | 154 ImportPersistentHistograms(); |
155 | 155 |
156 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_); | 156 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_); |
157 if (!histogram) { | 157 if (!histogram) { |
158 // To avoid racy destruction at shutdown, the following will be leaked. | 158 // To avoid racy destruction at shutdown, the following will be leaked. |
159 const BucketRanges* created_ranges = CreateRanges(); | 159 scoped_ptr<const BucketRanges> created_ranges(CreateRanges()); |
160 const BucketRanges* registered_ranges = | 160 const BucketRanges* registered_ranges = |
161 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(created_ranges); | 161 StatisticsRecorder::RegisterOrDeleteDuplicateRanges( |
| 162 std::move(created_ranges)); |
162 | 163 |
163 // In most cases, the bucket-count, minimum, and maximum values are known | 164 // In most cases, the bucket-count, minimum, and maximum values are known |
164 // when the code is written and so are passed in explicitly. In other | 165 // when the code is written and so are passed in explicitly. In other |
165 // cases (such as with a CustomHistogram), they are calculated dynamically | 166 // cases (such as with a CustomHistogram), they are calculated dynamically |
166 // at run-time. In the latter case, those ctor parameters are zero and | 167 // at run-time. In the latter case, those ctor parameters are zero and |
167 // the results extracted from the result of CreateRanges(). | 168 // the results extracted from the result of CreateRanges(). |
168 if (bucket_count_ == 0) { | 169 if (bucket_count_ == 0) { |
169 bucket_count_ = static_cast<uint32_t>(registered_ranges->bucket_count()); | 170 bucket_count_ = static_cast<uint32_t>(registered_ranges->bucket_count()); |
170 minimum_ = registered_ranges->range(1); | 171 minimum_ = registered_ranges->range(1); |
171 maximum_ = registered_ranges->range(bucket_count_ - 1); | 172 maximum_ = registered_ranges->range(bucket_count_ - 1); |
172 } | 173 } |
173 | 174 |
174 // Try to create the histogram using a "persistent" allocator. As of | 175 // Try to create the histogram using a "persistent" allocator. As of |
175 // 2015-01-14, the availability of such is controlled by a base::Feature | 176 // 2015-01-14, the availability of such is controlled by a base::Feature |
176 // that is off by default. If the allocator doesn't exist or if | 177 // that is off by default. If the allocator doesn't exist or if |
177 // allocating from it fails, code below will allocate the histogram from | 178 // allocating from it fails, code below will allocate the histogram from |
178 // the process heap. | 179 // the process heap. |
179 PersistentMemoryAllocator::Reference histogram_ref = 0; | 180 PersistentMemoryAllocator::Reference histogram_ref = 0; |
180 HistogramBase* tentative_histogram = nullptr; | 181 scoped_ptr<HistogramBase> tentative_histogram; |
181 PersistentMemoryAllocator* allocator = | 182 PersistentMemoryAllocator* allocator = |
182 GetPersistentHistogramMemoryAllocator(); | 183 GetPersistentHistogramMemoryAllocator(); |
183 if (allocator) { | 184 if (allocator) { |
184 flags_ |= HistogramBase::kIsPersistent; | 185 flags_ |= HistogramBase::kIsPersistent; |
185 tentative_histogram = AllocatePersistentHistogram( | 186 tentative_histogram = AllocatePersistentHistogram( |
186 allocator, | 187 allocator, |
187 histogram_type_, | 188 histogram_type_, |
188 name_, | 189 name_, |
189 minimum_, | 190 minimum_, |
190 maximum_, | 191 maximum_, |
191 registered_ranges, | 192 registered_ranges, |
192 flags_, | 193 flags_, |
193 &histogram_ref); | 194 &histogram_ref); |
194 } | 195 } |
195 | 196 |
196 // Handle the case where no persistent allocator is present or the | 197 // Handle the case where no persistent allocator is present or the |
197 // persistent allocation fails (perhaps because it is full). | 198 // persistent allocation fails (perhaps because it is full). |
198 if (!tentative_histogram) { | 199 if (!tentative_histogram) { |
199 DCHECK(!histogram_ref); // Should never have been set. | 200 DCHECK(!histogram_ref); // Should never have been set. |
200 DCHECK(!allocator); // Shouldn't have failed. | 201 DCHECK(!allocator); // Shouldn't have failed. |
201 flags_ &= ~HistogramBase::kIsPersistent; | 202 flags_ &= ~HistogramBase::kIsPersistent; |
202 tentative_histogram = HeapAlloc(registered_ranges); | 203 tentative_histogram.reset(HeapAlloc(registered_ranges)); |
203 } | 204 } |
204 | 205 |
205 FillHistogram(tentative_histogram); | 206 FillHistogram(tentative_histogram.get()); |
206 histogram = | 207 const void* allocated_histogram = tentative_histogram.get(); |
207 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); | 208 histogram = StatisticsRecorder::RegisterOrDeleteDuplicate( |
| 209 std::move(tentative_histogram)); |
208 | 210 |
209 // Persistent histograms need some follow-up processing. | 211 // Persistent histograms need some follow-up processing. |
210 if (histogram_ref) { | 212 if (histogram_ref) { |
211 FinalizePersistentHistogram(histogram_ref, | 213 FinalizePersistentHistogram(histogram_ref, |
212 histogram == tentative_histogram); | 214 histogram == allocated_histogram); |
213 } | 215 } |
214 } | 216 } |
215 | 217 |
216 DCHECK_EQ(histogram_type_, histogram->GetHistogramType()); | 218 DCHECK_EQ(histogram_type_, histogram->GetHistogramType()); |
217 if (bucket_count_ != 0 && | 219 if (bucket_count_ != 0 && |
218 !histogram->HasConstructionArguments(minimum_, maximum_, bucket_count_)) { | 220 !histogram->HasConstructionArguments(minimum_, maximum_, bucket_count_)) { |
219 // The construction arguments do not match the existing histogram. This can | 221 // The construction arguments do not match the existing histogram. This can |
220 // come about if an extension updates in the middle of a chrome run and has | 222 // come about if an extension updates in the middle of a chrome run and has |
221 // changed one of them, or simply by bad code within Chrome itself. We | 223 // changed one of them, or simply by bad code within Chrome itself. We |
222 // return NULL here with the expectation that bad code in Chrome will crash | 224 // return NULL here with the expectation that bad code in Chrome will crash |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 Sample sample = custom_ranges[i]; | 1157 Sample sample = custom_ranges[i]; |
1156 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) | 1158 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) |
1157 return false; | 1159 return false; |
1158 if (sample != 0) | 1160 if (sample != 0) |
1159 has_valid_range = true; | 1161 has_valid_range = true; |
1160 } | 1162 } |
1161 return has_valid_range; | 1163 return has_valid_range; |
1162 } | 1164 } |
1163 | 1165 |
1164 } // namespace base | 1166 } // namespace base |
OLD | NEW |