| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #include "base/metrics/persistent_histogram_allocator.h" | 5 #include "base/metrics/persistent_histogram_allocator.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/atomicops.h" | 9 #include "base/atomicops.h" |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 std::move(shm), 0, StringPiece(), /*readonly=*/false)))); | 818 std::move(shm), 0, StringPiece(), /*readonly=*/false)))); |
| 819 } | 819 } |
| 820 | 820 |
| 821 // static | 821 // static |
| 822 void GlobalHistogramAllocator::Set( | 822 void GlobalHistogramAllocator::Set( |
| 823 std::unique_ptr<GlobalHistogramAllocator> allocator) { | 823 std::unique_ptr<GlobalHistogramAllocator> allocator) { |
| 824 // Releasing or changing an allocator is extremely dangerous because it | 824 // Releasing or changing an allocator is extremely dangerous because it |
| 825 // likely has histograms stored within it. If the backing memory is also | 825 // likely has histograms stored within it. If the backing memory is also |
| 826 // also released, future accesses to those histograms will seg-fault. | 826 // also released, future accesses to those histograms will seg-fault. |
| 827 CHECK(!subtle::NoBarrier_Load(&g_allocator)); | 827 CHECK(!subtle::NoBarrier_Load(&g_allocator)); |
| 828 subtle::NoBarrier_Store(&g_allocator, | 828 subtle::Release_Store(&g_allocator, |
| 829 reinterpret_cast<uintptr_t>(allocator.release())); | 829 reinterpret_cast<uintptr_t>(allocator.release())); |
| 830 size_t existing = StatisticsRecorder::GetHistogramCount(); | 830 size_t existing = StatisticsRecorder::GetHistogramCount(); |
| 831 | 831 |
| 832 DVLOG_IF(1, existing) | 832 DVLOG_IF(1, existing) |
| 833 << existing << " histograms were created before persistence was enabled."; | 833 << existing << " histograms were created before persistence was enabled."; |
| 834 } | 834 } |
| 835 | 835 |
| 836 // static | 836 // static |
| 837 GlobalHistogramAllocator* GlobalHistogramAllocator::Get() { | 837 GlobalHistogramAllocator* GlobalHistogramAllocator::Get() { |
| 838 return reinterpret_cast<GlobalHistogramAllocator*>( | 838 return reinterpret_cast<GlobalHistogramAllocator*>( |
| 839 subtle::NoBarrier_Load(&g_allocator)); | 839 subtle::Acquire_Load(&g_allocator)); |
| 840 } | 840 } |
| 841 | 841 |
| 842 // static | 842 // static |
| 843 std::unique_ptr<GlobalHistogramAllocator> | 843 std::unique_ptr<GlobalHistogramAllocator> |
| 844 GlobalHistogramAllocator::ReleaseForTesting() { | 844 GlobalHistogramAllocator::ReleaseForTesting() { |
| 845 GlobalHistogramAllocator* histogram_allocator = Get(); | 845 GlobalHistogramAllocator* histogram_allocator = Get(); |
| 846 if (!histogram_allocator) | 846 if (!histogram_allocator) |
| 847 return nullptr; | 847 return nullptr; |
| 848 PersistentMemoryAllocator* memory_allocator = | 848 PersistentMemoryAllocator* memory_allocator = |
| 849 histogram_allocator->memory_allocator(); | 849 histogram_allocator->memory_allocator(); |
| 850 | 850 |
| 851 // Before releasing the memory, it's necessary to have the Statistics- | 851 // Before releasing the memory, it's necessary to have the Statistics- |
| 852 // Recorder forget about the histograms contained therein; otherwise, | 852 // Recorder forget about the histograms contained therein; otherwise, |
| 853 // some operations will try to access them and the released memory. | 853 // some operations will try to access them and the released memory. |
| 854 PersistentMemoryAllocator::Iterator iter(memory_allocator); | 854 PersistentMemoryAllocator::Iterator iter(memory_allocator); |
| 855 const PersistentHistogramData* data; | 855 const PersistentHistogramData* data; |
| 856 while ((data = iter.GetNextOfObject<PersistentHistogramData>()) != nullptr) { | 856 while ((data = iter.GetNextOfObject<PersistentHistogramData>()) != nullptr) { |
| 857 StatisticsRecorder::ForgetHistogramForTesting(data->name); | 857 StatisticsRecorder::ForgetHistogramForTesting(data->name); |
| 858 | 858 |
| 859 // If a test breaks here then a memory region containing a histogram | 859 // If a test breaks here then a memory region containing a histogram |
| 860 // actively used by this code is being released back to the test. | 860 // actively used by this code is being released back to the test. |
| 861 // If that memory segment were to be deleted, future calls to create | 861 // If that memory segment were to be deleted, future calls to create |
| 862 // persistent histograms would crash. To avoid this, have the test call | 862 // persistent histograms would crash. To avoid this, have the test call |
| 863 // the method GetCreateHistogramResultHistogram() *before* setting | 863 // the method GetCreateHistogramResultHistogram() *before* setting |
| 864 // the (temporary) memory allocator via SetGlobalAllocator() so that | 864 // the (temporary) memory allocator via SetGlobalAllocator() so that |
| 865 // histogram is instead allocated from the process heap. | 865 // histogram is instead allocated from the process heap. |
| 866 DCHECK_NE(kResultHistogram, data->name); | 866 DCHECK_NE(kResultHistogram, data->name); |
| 867 } | 867 } |
| 868 | 868 |
| 869 subtle::NoBarrier_Store(&g_allocator, 0); | 869 subtle::Release_Store(&g_allocator, 0); |
| 870 return WrapUnique(histogram_allocator); | 870 return WrapUnique(histogram_allocator); |
| 871 }; | 871 }; |
| 872 | 872 |
| 873 void GlobalHistogramAllocator::SetPersistentLocation(const FilePath& location) { | 873 void GlobalHistogramAllocator::SetPersistentLocation(const FilePath& location) { |
| 874 persistent_location_ = location; | 874 persistent_location_ = location; |
| 875 } | 875 } |
| 876 | 876 |
| 877 const FilePath& GlobalHistogramAllocator::GetPersistentLocation() const { | 877 const FilePath& GlobalHistogramAllocator::GetPersistentLocation() const { |
| 878 return persistent_location_; | 878 return persistent_location_; |
| 879 } | 879 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 while (true) { | 943 while (true) { |
| 944 std::unique_ptr<HistogramBase> histogram = | 944 std::unique_ptr<HistogramBase> histogram = |
| 945 import_iterator_.GetNextWithIgnore(record_to_ignore); | 945 import_iterator_.GetNextWithIgnore(record_to_ignore); |
| 946 if (!histogram) | 946 if (!histogram) |
| 947 break; | 947 break; |
| 948 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); | 948 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); |
| 949 } | 949 } |
| 950 } | 950 } |
| 951 | 951 |
| 952 } // namespace base | 952 } // namespace base |
| OLD | NEW |