| Index: base/metrics/persistent_histogram_allocator.cc
|
| diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
|
| index 62d4e5af9a718894b9bfabf78b16ddbbf569e2fb..6cf22de5d3302af4befaa2adea91cbbd8484026e 100644
|
| --- a/base/metrics/persistent_histogram_allocator.cc
|
| +++ b/base/metrics/persistent_histogram_allocator.cc
|
| @@ -35,11 +35,8 @@ const char kResultHistogram[] = "UMA.CreatePersistentHistogram.Result";
|
| // so that, if the structure of that object changes, stored older versions
|
| // will be safely ignored.
|
| enum : uint32_t {
|
| - kTypeIdHistogram = 0xF1645910 + 3, // SHA1(Histogram) v3
|
| kTypeIdRangesArray = 0xBCEA225A + 1, // SHA1(RangesArray) v1
|
| kTypeIdCountsArray = 0x53215530 + 1, // SHA1(CountsArray) v1
|
| -
|
| - kTypeIdHistogramUnderConstruction = ~kTypeIdHistogram,
|
| };
|
|
|
| // The current globally-active persistent allocator for all new histograms.
|
| @@ -226,6 +223,9 @@ PersistentMemoryAllocator::Reference PersistentSampleMapRecords::CreateNew(
|
| // This data will be held in persistent memory in order for processes to
|
| // locate and use histograms created elsewhere.
|
| struct PersistentHistogramAllocator::PersistentHistogramData {
|
| + // SHA1(Histogram): Increment this if structure changes!
|
| + static constexpr uint32_t kPersistentTypeId = 0xF1645910 + 3;
|
| +
|
| // Expected size for 32/64-bit check.
|
| static constexpr size_t kExpectedInstanceSize =
|
| 40 + 2 * HistogramSamples::Metadata::kExpectedInstanceSize;
|
| @@ -254,7 +254,7 @@ PersistentHistogramAllocator::Iterator::Iterator(
|
| std::unique_ptr<HistogramBase>
|
| PersistentHistogramAllocator::Iterator::GetNextWithIgnore(Reference ignore) {
|
| PersistentMemoryAllocator::Reference ref;
|
| - while ((ref = memory_iter_.GetNextOfType(kTypeIdHistogram)) != 0) {
|
| + while ((ref = memory_iter_.GetNextOfType<PersistentHistogramData>()) != 0) {
|
| if (ref != ignore)
|
| return allocator_->GetHistogram(ref);
|
| }
|
| @@ -277,8 +277,7 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
|
| // add it to the local list of known histograms (while these may be simple
|
| // references to histograms in other processes).
|
| PersistentHistogramData* histogram_data =
|
| - memory_allocator_->GetAsObject<PersistentHistogramData>(
|
| - ref, kTypeIdHistogram);
|
| + memory_allocator_->GetAsObject<PersistentHistogramData>(ref);
|
| size_t length = memory_allocator_->GetAllocSize(ref);
|
|
|
| // Check that metadata is reasonable: name is NUL terminated and non-empty,
|
| @@ -319,13 +318,9 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
|
| // during the datafill doesn't leave a bad record around that could cause
|
| // confusion by another process trying to read it. It will be corrected
|
| // once histogram construction is complete.
|
| - PersistentMemoryAllocator::Reference histogram_ref =
|
| - memory_allocator_->Allocate(
|
| - offsetof(PersistentHistogramData, name) + name.length() + 1,
|
| - kTypeIdHistogramUnderConstruction);
|
| PersistentHistogramData* histogram_data =
|
| - memory_allocator_->GetAsObject<PersistentHistogramData>(
|
| - histogram_ref, kTypeIdHistogramUnderConstruction);
|
| + memory_allocator_->AllocateObject<PersistentHistogramData>(
|
| + offsetof(PersistentHistogramData, name) + name.length() + 1);
|
| if (histogram_data) {
|
| memcpy(histogram_data->name, name.c_str(), name.size() + 1);
|
| histogram_data->histogram_type = histogram_type;
|
| @@ -384,9 +379,9 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
|
| DCHECK(histogram);
|
| DCHECK_NE(0U, histogram_data->samples_metadata.id);
|
| DCHECK_NE(0U, histogram_data->logged_metadata.id);
|
| - memory_allocator_->ChangeType(histogram_ref, kTypeIdHistogram,
|
| - kTypeIdHistogramUnderConstruction);
|
|
|
| + PersistentMemoryAllocator::Reference histogram_ref =
|
| + memory_allocator_->GetAsReference(histogram_data);
|
| if (ref_ptr != nullptr)
|
| *ref_ptr = histogram_ref;
|
|
|
| @@ -415,15 +410,19 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
|
|
|
| void PersistentHistogramAllocator::FinalizeHistogram(Reference ref,
|
| bool registered) {
|
| - // If the created persistent histogram was registered then it needs to
|
| - // be marked as "iterable" in order to be found by other processes.
|
| - if (registered)
|
| + if (registered) {
|
| + // If the created persistent histogram was registered then it needs to
|
| + // be marked as "iterable" in order to be found by other processes. This
|
| + // happens only after the histogram is fully formed so it's impossible for
|
| + // code iterating through the allocator to read a partially created record.
|
| memory_allocator_->MakeIterable(ref);
|
| - // If it wasn't registered then a race condition must have caused
|
| - // two to be created. The allocator does not support releasing the
|
| - // acquired memory so just change the type to be empty.
|
| - else
|
| - memory_allocator_->ChangeType(ref, 0, kTypeIdHistogram);
|
| + } else {
|
| + // If it wasn't registered then a race condition must have caused two to
|
| + // be created. The allocator does not support releasing the acquired memory
|
| + // so just change the type to be empty.
|
| + memory_allocator_->ChangeType(ref, 0,
|
| + PersistentHistogramData::kPersistentTypeId);
|
| + }
|
| }
|
|
|
| void PersistentHistogramAllocator::MergeHistogramDeltaToStatisticsRecorder(
|
| @@ -842,13 +841,9 @@ GlobalHistogramAllocator::ReleaseForTesting() {
|
| // Recorder forget about the histograms contained therein; otherwise,
|
| // some operations will try to access them and the released memory.
|
| PersistentMemoryAllocator::Iterator iter(memory_allocator);
|
| - PersistentMemoryAllocator::Reference ref;
|
| - while ((ref = iter.GetNextOfType(kTypeIdHistogram)) != 0) {
|
| - PersistentHistogramData* histogram_data =
|
| - memory_allocator->GetAsObject<PersistentHistogramData>(
|
| - ref, kTypeIdHistogram);
|
| - DCHECK(histogram_data);
|
| - StatisticsRecorder::ForgetHistogramForTesting(histogram_data->name);
|
| + const PersistentHistogramData* data;
|
| + while ((data = iter.GetNextOfObject<PersistentHistogramData>()) != nullptr) {
|
| + StatisticsRecorder::ForgetHistogramForTesting(data->name);
|
|
|
| // If a test breaks here then a memory region containing a histogram
|
| // actively used by this code is being released back to the test.
|
| @@ -857,7 +852,7 @@ GlobalHistogramAllocator::ReleaseForTesting() {
|
| // the method GetCreateHistogramResultHistogram() *before* setting
|
| // the (temporary) memory allocator via SetGlobalAllocator() so that
|
| // histogram is instead allocated from the process heap.
|
| - DCHECK_NE(kResultHistogram, histogram_data->name);
|
| + DCHECK_NE(kResultHistogram, data->name);
|
| }
|
|
|
| g_allocator = nullptr;
|
|
|