| 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 #include "base/metrics/statistics_recorder.h" | 5 #include "base/metrics/statistics_recorder.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/debug/leak_annotations.h" | 10 #include "base/debug/leak_annotations.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 if (!histograms_) { | 86 if (!histograms_) { |
| 87 histogram_to_return = histogram; | 87 histogram_to_return = histogram; |
| 88 | 88 |
| 89 // As per crbug.com/79322 the histograms are intentionally leaked, so we | 89 // As per crbug.com/79322 the histograms are intentionally leaked, so we |
| 90 // need to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used | 90 // need to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used |
| 91 // only once for an object, the duplicates should not be annotated. | 91 // only once for an object, the duplicates should not be annotated. |
| 92 // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr) | 92 // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr) |
| 93 // twice |if (!histograms_)|. | 93 // twice |if (!histograms_)|. |
| 94 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 | 94 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 |
| 95 } else { | 95 } else { |
| 96 const std::string& name = histogram->histogram_name(); | 96 const char* name = histogram->histogram_name(); |
| 97 HistogramMap::iterator it = histograms_->find(name); | 97 StringPiece name_piece = name; |
| 98 HistogramMap::iterator it = histograms_->find(name_piece); |
| 98 if (histograms_->end() == it) { | 99 if (histograms_->end() == it) { |
| 99 // The StringKey references the name within |histogram| rather than | 100 // The StringKey references the name within |histogram| rather than |
| 100 // making a copy. | 101 // making a copy. |
| 101 (*histograms_)[name] = histogram; | 102 (*histograms_)[name_piece] = histogram; |
| 102 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 | 103 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 |
| 103 // If there are callbacks for this histogram, we set the kCallbackExists | 104 // If there are callbacks for this histogram, we set the kCallbackExists |
| 104 // flag. | 105 // flag. |
| 105 auto callback_iterator = callbacks_->find(name); | 106 auto callback_iterator = callbacks_->find(name); |
| 106 if (callback_iterator != callbacks_->end()) { | 107 if (callback_iterator != callbacks_->end()) { |
| 107 if (!callback_iterator->second.is_null()) | 108 if (!callback_iterator->second.is_null()) |
| 108 histogram->SetFlags(HistogramBase::kCallbackExists); | 109 histogram->SetFlags(HistogramBase::kCallbackExists); |
| 109 else | 110 else |
| 110 histogram->ClearFlags(HistogramBase::kCallbackExists); | 111 histogram->ClearFlags(HistogramBase::kCallbackExists); |
| 111 } | 112 } |
| 112 histogram_to_return = histogram; | 113 histogram_to_return = histogram; |
| 113 } else if (histogram == it->second) { | 114 } else if (histogram == it->second) { |
| 114 // The histogram was registered before. | 115 // The histogram was registered before. |
| 115 histogram_to_return = histogram; | 116 histogram_to_return = histogram; |
| 116 } else { | 117 } else { |
| 117 // We already have one histogram with this name. | 118 // We already have one histogram with this name. |
| 118 DCHECK_EQ(histogram->histogram_name(), | 119 DCHECK_EQ(StringPiece(histogram->histogram_name()), |
| 119 it->second->histogram_name()) << "hash collision"; | 120 StringPiece(it->second->histogram_name())) |
| 121 << "hash collision"; |
| 120 histogram_to_return = it->second; | 122 histogram_to_return = it->second; |
| 121 histogram_to_delete = histogram; | 123 histogram_to_delete = histogram; |
| 122 } | 124 } |
| 123 } | 125 } |
| 124 } | 126 } |
| 125 delete histogram_to_delete; | 127 delete histogram_to_delete; |
| 126 return histogram_to_return; | 128 return histogram_to_return; |
| 127 } | 129 } |
| 128 | 130 |
| 129 // static | 131 // static |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 Histograms* snapshot) { | 324 Histograms* snapshot) { |
| 323 // This must be called *before* the lock is acquired below because it will | 325 // This must be called *before* the lock is acquired below because it will |
| 324 // call back into this object to register histograms. Those called methods | 326 // call back into this object to register histograms. Those called methods |
| 325 // will acquire the lock at that time. | 327 // will acquire the lock at that time. |
| 326 ImportGlobalPersistentHistograms(); | 328 ImportGlobalPersistentHistograms(); |
| 327 | 329 |
| 328 base::AutoLock auto_lock(lock_.Get()); | 330 base::AutoLock auto_lock(lock_.Get()); |
| 329 if (!histograms_) | 331 if (!histograms_) |
| 330 return; | 332 return; |
| 331 | 333 |
| 334 // Need a c-string query for comparisons against c-string histogram name. |
| 335 const char* query_string = query.c_str(); |
| 336 |
| 332 for (const auto& entry : *histograms_) { | 337 for (const auto& entry : *histograms_) { |
| 333 if (entry.second->histogram_name().find(query) != std::string::npos) | 338 if (strstr(entry.second->histogram_name(), query_string) != nullptr) |
| 334 snapshot->push_back(entry.second); | 339 snapshot->push_back(entry.second); |
| 335 } | 340 } |
| 336 } | 341 } |
| 337 | 342 |
| 338 // static | 343 // static |
| 339 bool StatisticsRecorder::SetCallback( | 344 bool StatisticsRecorder::SetCallback( |
| 340 const std::string& name, | 345 const std::string& name, |
| 341 const StatisticsRecorder::OnSampleCallback& cb) { | 346 const StatisticsRecorder::OnSampleCallback& cb) { |
| 342 DCHECK(!cb.is_null()); | 347 DCHECK(!cb.is_null()); |
| 343 base::AutoLock auto_lock(lock_.Get()); | 348 base::AutoLock auto_lock(lock_.Get()); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr; | 534 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr; |
| 530 // static | 535 // static |
| 531 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr; | 536 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr; |
| 532 // static | 537 // static |
| 533 StatisticsRecorder::HistogramProviders* StatisticsRecorder::providers_; | 538 StatisticsRecorder::HistogramProviders* StatisticsRecorder::providers_; |
| 534 // static | 539 // static |
| 535 base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ = | 540 base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ = |
| 536 LAZY_INSTANCE_INITIALIZER; | 541 LAZY_INSTANCE_INITIALIZER; |
| 537 | 542 |
| 538 } // namespace base | 543 } // namespace base |
| OLD | NEW |