Chromium Code Reviews| Index: base/metrics/histogram_persistence.cc |
| diff --git a/base/metrics/histogram_persistence.cc b/base/metrics/histogram_persistence.cc |
| index f18d17528354329cd4995615d2451f6a52c59302..77515fffe9e3333899330aa751b751184ec3f574 100644 |
| --- a/base/metrics/histogram_persistence.cc |
| +++ b/base/metrics/histogram_persistence.cc |
| @@ -10,6 +10,7 @@ |
| #include "base/metrics/histogram.h" |
| #include "base/metrics/histogram_base.h" |
| #include "base/metrics/histogram_samples.h" |
| +#include "base/metrics/sparse_histogram.h" |
| #include "base/metrics/statistics_recorder.h" |
| #include "base/synchronization/lock.h" |
| @@ -238,6 +239,17 @@ HistogramBase* CreatePersistentHistogram( |
| return nullptr; |
| } |
| + // Sparse histograms are quite different so handle them as a special case. |
| + if (histogram_data_ptr->histogram_type == SPARSE_HISTOGRAM) { |
| + HistogramBase* histogram = SparseHistogram::PersistentGet( |
| + allocator, |
| + histogram_data_ptr->name, |
| + &histogram_data_ptr->samples_metadata, |
| + &histogram_data_ptr->logged_metadata); |
| + DCHECK(histogram); |
| + return histogram; |
| + } |
| + |
| // Copy the histogram_data to local storage because anything in persistent |
| // memory cannot be trusted as it could be changed at any moment by a |
| // malicious actor that shares access. The contents of histogram_data are |
| @@ -419,48 +431,68 @@ HistogramBase* AllocatePersistentHistogram( |
| return nullptr; |
| } |
| - // If CalculateRequiredCountsBytes() returns zero then the bucket_count |
| - // was not valid. |
| - size_t bucket_count = bucket_ranges->bucket_count(); |
| - size_t counts_bytes = CalculateRequiredCountsBytes(bucket_count); |
| - if (!counts_bytes) { |
| - NOTREACHED(); |
| - return nullptr; |
| - } |
| + // Create all the metadata necessary for a persistent histogram. Sparse |
| + // histograms are quite different so handle them as a special case. |
| + PersistentMemoryAllocator::Reference histogram_ref = 0; |
| + PersistentHistogramData* histogram_data = nullptr; |
| + if (histogram_type == SPARSE_HISTOGRAM) { |
| + histogram_ref = allocator->Allocate( |
| + offsetof(PersistentHistogramData, name) + name.length() + 1, |
| + kTypeIdHistogram); |
| + histogram_data = allocator->GetAsObject<PersistentHistogramData>( |
| + histogram_ref, kTypeIdHistogram); |
| + if (histogram_data) { |
| + strcpy(histogram_data->name, name.c_str()); |
| + histogram_data->histogram_type = histogram_type; |
| + histogram_data->flags = flags; |
| + } |
| + } else { |
| + // If CalculateRequiredCountsBytes() returns zero then the bucket_count |
|
grt (UTC plus 2)
2016/03/02 20:00:42
nit: move this comment into the "!counts_bytes" bl
bcwhite
2016/03/02 22:32:43
Done.
|
| + // was not valid. |
| + size_t bucket_count = bucket_ranges->bucket_count(); |
| + size_t counts_bytes = CalculateRequiredCountsBytes(bucket_count); |
| + if (!counts_bytes) { |
| + NOTREACHED(); |
| + return nullptr; |
| + } |
| - size_t ranges_bytes = (bucket_count + 1) * sizeof(HistogramBase::Sample); |
| - PersistentMemoryAllocator::Reference ranges_ref = |
| - allocator->Allocate(ranges_bytes, kTypeIdRangesArray); |
| - PersistentMemoryAllocator::Reference counts_ref = |
| - allocator->Allocate(counts_bytes, kTypeIdCountsArray); |
| - PersistentMemoryAllocator::Reference histogram_ref = |
| - allocator->Allocate(offsetof(PersistentHistogramData, name) + |
| - name.length() + 1, kTypeIdHistogram); |
| - HistogramBase::Sample* ranges_data = |
| - allocator->GetAsObject<HistogramBase::Sample>(ranges_ref, |
| - kTypeIdRangesArray); |
| - PersistentHistogramData* histogram_data = |
| - allocator->GetAsObject<PersistentHistogramData>(histogram_ref, |
| - kTypeIdHistogram); |
| - |
| - // Only continue here if all allocations were successful. If they weren't |
| - // there is no way to free the space but that's not really a problem since |
| - // the allocations only fail because the space is full and so any future |
| - // attempts will also fail. |
| - if (counts_ref && ranges_data && histogram_data) { |
| - strcpy(histogram_data->name, name.c_str()); |
| - for (size_t i = 0; i < bucket_ranges->size(); ++i) |
| - ranges_data[i] = bucket_ranges->range(i); |
| - |
| - histogram_data->histogram_type = histogram_type; |
| - histogram_data->flags = flags; |
| - histogram_data->minimum = minimum; |
| - histogram_data->maximum = maximum; |
| - histogram_data->bucket_count = static_cast<uint32_t>(bucket_count); |
| - histogram_data->ranges_ref = ranges_ref; |
| - histogram_data->ranges_checksum = bucket_ranges->checksum(); |
| - histogram_data->counts_ref = counts_ref; |
| + size_t ranges_bytes = (bucket_count + 1) * sizeof(HistogramBase::Sample); |
| + PersistentMemoryAllocator::Reference counts_ref = |
| + allocator->Allocate(counts_bytes, kTypeIdCountsArray); |
| + PersistentMemoryAllocator::Reference ranges_ref = |
| + allocator->Allocate(ranges_bytes, kTypeIdRangesArray); |
| + HistogramBase::Sample* ranges_data = |
| + allocator->GetAsObject<HistogramBase::Sample>(ranges_ref, |
| + kTypeIdRangesArray); |
| + histogram_ref = allocator->Allocate( |
| + offsetof(PersistentHistogramData, name) + name.length() + 1, |
| + kTypeIdHistogram); |
| + histogram_data = allocator->GetAsObject<PersistentHistogramData>( |
| + histogram_ref, kTypeIdHistogram); |
| + |
| + // Only continue here if all allocations were successful. If they weren't |
| + // there is no way to free the space but that's not really a problem since |
| + // the allocations only fail because the space is full and so any future |
| + // attempts will also fail. |
| + if (counts_ref && ranges_data && histogram_data) { |
| + strcpy(histogram_data->name, name.c_str()); |
|
grt (UTC plus 2)
2016/03/02 20:00:42
nit: use memcpy since you know the size
bcwhite
2016/03/02 22:32:43
Done.
|
| + for (size_t i = 0; i < bucket_ranges->size(); ++i) |
| + ranges_data[i] = bucket_ranges->range(i); |
| + |
| + histogram_data->histogram_type = histogram_type; |
| + histogram_data->flags = flags; |
| + histogram_data->minimum = minimum; |
| + histogram_data->maximum = maximum; |
| + histogram_data->bucket_count = static_cast<uint32_t>(bucket_count); |
|
grt (UTC plus 2)
2016/03/02 20:00:42
i think this is safe on account of CalculateRequir
bcwhite
2016/03/02 22:32:43
It's actually limited because any allocation that
|
| + histogram_data->ranges_ref = ranges_ref; |
| + histogram_data->ranges_checksum = bucket_ranges->checksum(); |
| + histogram_data->counts_ref = counts_ref; |
| + } else { |
| + histogram_data = nullptr; // Clear this for proper handling below. |
| + } |
| + } |
| + if (histogram_data) { |
| // Create the histogram using resources in persistent memory. This ends up |
| // resolving the "ref" values stored in histogram_data instad of just |
| // using what is already known above but avoids duplicating the switch |