| 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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 if (!histograms_) { | 129 if (!histograms_) { |
| 130 histogram_to_return = histogram; | 130 histogram_to_return = histogram; |
| 131 | 131 |
| 132 // As per crbug.com/79322 the histograms are intentionally leaked, so we | 132 // As per crbug.com/79322 the histograms are intentionally leaked, so we |
| 133 // need to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used | 133 // need to annotate them. Because ANNOTATE_LEAKING_OBJECT_PTR may be used |
| 134 // only once for an object, the duplicates should not be annotated. | 134 // only once for an object, the duplicates should not be annotated. |
| 135 // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr) | 135 // Callers are responsible for not calling RegisterOrDeleteDuplicate(ptr) |
| 136 // twice |if (!histograms_)|. | 136 // twice |if (!histograms_)|. |
| 137 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 | 137 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 |
| 138 } else { | 138 } else { |
| 139 const std::string& name = histogram->histogram_name(); | 139 const char* name = histogram->histogram_name(); |
| 140 HistogramMap::iterator it = histograms_->find(name); | 140 StringPiece name_piece = name; |
| 141 HistogramMap::iterator it = histograms_->find(name_piece); |
| 141 if (histograms_->end() == it) { | 142 if (histograms_->end() == it) { |
| 142 // The StringKey references the name within |histogram| rather than | 143 // The StringKey references the name within |histogram| rather than |
| 143 // making a copy. | 144 // making a copy. |
| 144 (*histograms_)[name] = histogram; | 145 (*histograms_)[name_piece] = histogram; |
| 145 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 | 146 ANNOTATE_LEAKING_OBJECT_PTR(histogram); // see crbug.com/79322 |
| 146 // If there are callbacks for this histogram, we set the kCallbackExists | 147 // If there are callbacks for this histogram, we set the kCallbackExists |
| 147 // flag. | 148 // flag. |
| 148 auto callback_iterator = callbacks_->find(name); | 149 auto callback_iterator = callbacks_->find(name); |
| 149 if (callback_iterator != callbacks_->end()) { | 150 if (callback_iterator != callbacks_->end()) { |
| 150 if (!callback_iterator->second.is_null()) | 151 if (!callback_iterator->second.is_null()) |
| 151 histogram->SetFlags(HistogramBase::kCallbackExists); | 152 histogram->SetFlags(HistogramBase::kCallbackExists); |
| 152 else | 153 else |
| 153 histogram->ClearFlags(HistogramBase::kCallbackExists); | 154 histogram->ClearFlags(HistogramBase::kCallbackExists); |
| 154 } | 155 } |
| 155 histogram_to_return = histogram; | 156 histogram_to_return = histogram; |
| 156 } else if (histogram == it->second) { | 157 } else if (histogram == it->second) { |
| 157 // The histogram was registered before. | 158 // The histogram was registered before. |
| 158 histogram_to_return = histogram; | 159 histogram_to_return = histogram; |
| 159 } else { | 160 } else { |
| 160 // We already have one histogram with this name. | 161 // We already have one histogram with this name. |
| 161 DCHECK_EQ(histogram->histogram_name(), | 162 DCHECK_EQ(StringPiece(histogram->histogram_name()), |
| 162 it->second->histogram_name()) << "hash collision"; | 163 StringPiece(it->second->histogram_name())) |
| 164 << "hash collision"; |
| 163 histogram_to_return = it->second; | 165 histogram_to_return = it->second; |
| 164 histogram_to_delete = histogram; | 166 histogram_to_delete = histogram; |
| 165 } | 167 } |
| 166 } | 168 } |
| 167 } | 169 } |
| 168 delete histogram_to_delete; | 170 delete histogram_to_delete; |
| 169 return histogram_to_return; | 171 return histogram_to_return; |
| 170 } | 172 } |
| 171 | 173 |
| 172 // static | 174 // static |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 | 364 |
| 363 // static | 365 // static |
| 364 void StatisticsRecorder::GetSnapshot(const std::string& query, | 366 void StatisticsRecorder::GetSnapshot(const std::string& query, |
| 365 Histograms* snapshot) { | 367 Histograms* snapshot) { |
| 366 base::AutoLock auto_lock(lock_.Get()); | 368 base::AutoLock auto_lock(lock_.Get()); |
| 367 if (!histograms_) | 369 if (!histograms_) |
| 368 return; | 370 return; |
| 369 | 371 |
| 370 ImportGlobalPersistentHistograms(); | 372 ImportGlobalPersistentHistograms(); |
| 371 | 373 |
| 374 // Need a c-string query for comparisons against c-string histogram name. |
| 375 const char* query_string = query.c_str(); |
| 376 |
| 372 for (const auto& entry : *histograms_) { | 377 for (const auto& entry : *histograms_) { |
| 373 if (entry.second->histogram_name().find(query) != std::string::npos) | 378 if (strstr(entry.second->histogram_name(), query_string) != nullptr) |
| 374 snapshot->push_back(entry.second); | 379 snapshot->push_back(entry.second); |
| 375 } | 380 } |
| 376 } | 381 } |
| 377 | 382 |
| 378 // static | 383 // static |
| 379 bool StatisticsRecorder::SetCallback( | 384 bool StatisticsRecorder::SetCallback( |
| 380 const std::string& name, | 385 const std::string& name, |
| 381 const StatisticsRecorder::OnSampleCallback& cb) { | 386 const StatisticsRecorder::OnSampleCallback& cb) { |
| 382 DCHECK(!cb.is_null()); | 387 DCHECK(!cb.is_null()); |
| 383 base::AutoLock auto_lock(lock_.Get()); | 388 base::AutoLock auto_lock(lock_.Get()); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr; | 554 StatisticsRecorder::CallbackMap* StatisticsRecorder::callbacks_ = nullptr; |
| 550 // static | 555 // static |
| 551 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr; | 556 StatisticsRecorder::RangesMap* StatisticsRecorder::ranges_ = nullptr; |
| 552 // static | 557 // static |
| 553 StatisticsRecorder::HistogramProviders* StatisticsRecorder::providers_; | 558 StatisticsRecorder::HistogramProviders* StatisticsRecorder::providers_; |
| 554 // static | 559 // static |
| 555 base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ = | 560 base::LazyInstance<base::Lock>::Leaky StatisticsRecorder::lock_ = |
| 556 LAZY_INSTANCE_INITIALIZER; | 561 LAZY_INSTANCE_INITIALIZER; |
| 557 | 562 |
| 558 } // namespace base | 563 } // namespace base |
| OLD | NEW |