Use bounded ranges (string_view) for histogram names.
This CL changes the histogram creation APIs to take a durable string view (i.e., a pointer+size pair referring to memory that the programmer has annotated that it will not be freed) instead of just an implicit pointer. The HistogramBase class internally represents the name's length and the histogram's flags using 16 bits in order to not grow the in-memory size of Histogram objects. The name of the histogram is subsequently exposed by HistogramBase as a string_view. This CL updates consumers of the histogram name's to use a string_view of the name. This removes many string length calculations and string copy operations. For histograms allocated in shared memory, it also avoids potential out-of- bounds reads if the underlying string data is modified or corrupted such that it no longer has a trailing NUL char at the end of the string. Lastly, this CL updates a number of call-sites where the histogram names were being copied into short-lived string objects for use as search keys into various containers to perform the functionality without making any unnecessary copies. Low-Coverage-Reason: TRIVIAL_CHANGE Use of string_view instead of string/char* in some error/logging paths have low coverage. AX-Relnotes: n/a Bug: 393394360, 40818143 Change-Id: Iee9ee5ae62335b9e7815f4ae11bde4ff80cfd4a2 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6231451 Reviewed-by: Avi Drissman <avi@chromium.org> Reviewed-by: Antonio Rivera <antoniori@google.com> Commit-Queue: Roger McFarlane <rogerm@chromium.org> Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org> Reviewed-by: Nico Weber <thakis@chromium.org> Cr-Commit-Position: refs/heads/main@{#1422750}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
a2d6b9176f
commit
8952859c39
base
BUILD.gn
android
metrics
dummy_histogram.hhistogram.cchistogram.hhistogram_base.cchistogram_base.hhistogram_base_unittest.cchistogram_snapshot_manager_unittest.cchistogram_threadsafe_unittest.ccpersistent_histogram_allocator.ccpersistent_histogram_allocator.hpersistent_histogram_allocator_unittest.ccsparse_histogram.ccsparse_histogram.hsparse_histogram_unittest.ccstatistics_recorder.ccstatistics_recorder.hstatistics_recorder_unittest.cc
strings
test
metrics
chrome/browser
ash
autofill
metrics
notifications
os_crypt
password_manager
privacy_sandbox
segmentation_platform
site_protection
ui
chromecast/base/metrics
chromeos/ash/services/ime/public/mojom
components
fuchsia_legacymetrics
metrics
content
file_metrics_provider_unittest.cchistogram_encoder.cchistogram_encoder.hmetrics_log.ccmetrics_log.hnet
segmentation_platform
internal
value_store
content/browser
devtools
metrics
shared_storage
tracing
ios/chrome
services/tracing/public/cpp
background_tracing
perfetto
third_party/webrtc_overrides
@ -589,6 +589,7 @@ component("base") {
|
||||
"strings/abseil_string_number_conversions.cc",
|
||||
"strings/abseil_string_number_conversions.h",
|
||||
"strings/cstring_view.h",
|
||||
"strings/durable_string_view.h",
|
||||
"strings/escape.cc",
|
||||
"strings/escape.h",
|
||||
"strings/latin1_string_conversions.cc",
|
||||
|
@ -2,10 +2,13 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "base/android/callback_android.h"
|
||||
#include "base/android/jni_android.h"
|
||||
#include "base/android/jni_array.h"
|
||||
#include "base/android/jni_string.h"
|
||||
#include "base/containers/map_util.h"
|
||||
#include "base/format_macros.h"
|
||||
#include "base/metrics/histogram.h"
|
||||
#include "base/metrics/histogram_base.h"
|
||||
@ -24,25 +27,25 @@ namespace android {
|
||||
namespace {
|
||||
|
||||
using HistogramsSnapshot =
|
||||
std::map<std::string, std::unique_ptr<HistogramSamples>>;
|
||||
std::map<std::string, std::unique_ptr<HistogramSamples>, std::less<>>;
|
||||
|
||||
std::string HistogramConstructionParamsToString(HistogramBase* histogram) {
|
||||
std::string params_str = histogram->histogram_name();
|
||||
std::string_view name = histogram->histogram_name();
|
||||
switch (histogram->GetHistogramType()) {
|
||||
case HISTOGRAM:
|
||||
case LINEAR_HISTOGRAM:
|
||||
case BOOLEAN_HISTOGRAM:
|
||||
case CUSTOM_HISTOGRAM: {
|
||||
Histogram* hist = static_cast<Histogram*>(histogram);
|
||||
params_str += StringPrintf("/%d/%d/%" PRIuS, hist->declared_min(),
|
||||
hist->declared_max(), hist->bucket_count());
|
||||
break;
|
||||
return StringPrintf("%.*s/%d/%d/%" PRIuS, name.length(), name.data(),
|
||||
hist->declared_min(), hist->declared_max(),
|
||||
hist->bucket_count());
|
||||
}
|
||||
case SPARSE_HISTOGRAM:
|
||||
case DUMMY_HISTOGRAM:
|
||||
break;
|
||||
}
|
||||
return params_str;
|
||||
return std::string(name);
|
||||
}
|
||||
|
||||
// Convert a jlong |histogram_hint| from Java to a HistogramBase* via a cast.
|
||||
@ -289,7 +292,8 @@ JNI_NativeUmaRecorder_GetHistogramSamplesForTesting(JNIEnv* env,
|
||||
jlong JNI_NativeUmaRecorder_CreateHistogramSnapshotForTesting(JNIEnv* env) {
|
||||
HistogramsSnapshot* snapshot = new HistogramsSnapshot();
|
||||
for (const auto* const histogram : StatisticsRecorder::GetHistograms()) {
|
||||
(*snapshot)[histogram->histogram_name()] = histogram->SnapshotSamples();
|
||||
InsertOrAssign(*snapshot, histogram->histogram_name(),
|
||||
histogram->SnapshotSamples());
|
||||
}
|
||||
return reinterpret_cast<intptr_t>(snapshot);
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class BASE_EXPORT DummyHistogram : public HistogramBase {
|
||||
private:
|
||||
friend class NoDestructor<DummyHistogram>;
|
||||
|
||||
DummyHistogram() : HistogramBase("dummy_histogram") {}
|
||||
DummyHistogram() : HistogramBase(DurableStringView("dummy_histogram")) {}
|
||||
~DummyHistogram() override = default;
|
||||
};
|
||||
|
||||
|
@ -317,14 +317,14 @@ HistogramBase* Histogram::FactoryMicrosecondsTimeGet(const char* name,
|
||||
}
|
||||
|
||||
std::unique_ptr<HistogramBase> Histogram::PersistentCreate(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta) {
|
||||
return WrapUnique(
|
||||
new Histogram(name, ranges, counts, logged_counts, meta, logged_meta));
|
||||
return WrapUnique(new Histogram(durable_name, ranges, counts, logged_counts,
|
||||
meta, logged_meta));
|
||||
}
|
||||
|
||||
// Calculate what range of values are held in each bucket.
|
||||
@ -623,25 +623,25 @@ void Histogram::SerializeInfoImpl(Pickle* pickle) const {
|
||||
pickle->WriteUInt32(bucket_ranges()->checksum());
|
||||
}
|
||||
|
||||
Histogram::Histogram(const char* name, const BucketRanges* ranges)
|
||||
: HistogramBase(name) {
|
||||
DCHECK(ranges) << name;
|
||||
Histogram::Histogram(DurableStringView durable_name, const BucketRanges* ranges)
|
||||
: HistogramBase(durable_name) {
|
||||
DCHECK(ranges) << histogram_name();
|
||||
unlogged_samples_ =
|
||||
std::make_unique<SampleVector>(HashMetricName(name), ranges);
|
||||
std::make_unique<SampleVector>(HashMetricName(histogram_name()), ranges);
|
||||
logged_samples_ =
|
||||
std::make_unique<SampleVector>(unlogged_samples_->id(), ranges);
|
||||
}
|
||||
|
||||
Histogram::Histogram(const char* name,
|
||||
Histogram::Histogram(DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta)
|
||||
: HistogramBase(name) {
|
||||
DCHECK(ranges) << name;
|
||||
: HistogramBase(durable_name) {
|
||||
DCHECK(ranges) << histogram_name();
|
||||
unlogged_samples_ = std::make_unique<PersistentSampleVector>(
|
||||
HashMetricName(name), ranges, meta, counts);
|
||||
HashMetricName(histogram_name()), ranges, meta, counts);
|
||||
logged_samples_ = std::make_unique<PersistentSampleVector>(
|
||||
unlogged_samples_->id(), ranges, logged_meta, logged_counts);
|
||||
}
|
||||
@ -860,14 +860,14 @@ HistogramBase* LinearHistogram::FactoryTimeGet(const char* name,
|
||||
}
|
||||
|
||||
std::unique_ptr<HistogramBase> LinearHistogram::PersistentCreate(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta) {
|
||||
return WrapUnique(new LinearHistogram(name, ranges, counts, logged_counts,
|
||||
meta, logged_meta));
|
||||
return WrapUnique(new LinearHistogram(durable_name, ranges, counts,
|
||||
logged_counts, meta, logged_meta));
|
||||
}
|
||||
|
||||
HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
|
||||
@ -905,17 +905,23 @@ HistogramType LinearHistogram::GetHistogramType() const {
|
||||
return LINEAR_HISTOGRAM;
|
||||
}
|
||||
|
||||
LinearHistogram::LinearHistogram(const char* name, const BucketRanges* ranges)
|
||||
: Histogram(name, ranges) {}
|
||||
LinearHistogram::LinearHistogram(DurableStringView durable_name,
|
||||
const BucketRanges* ranges)
|
||||
: Histogram(durable_name, ranges) {}
|
||||
|
||||
LinearHistogram::LinearHistogram(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta)
|
||||
: Histogram(name, ranges, counts, logged_counts, meta, logged_meta) {}
|
||||
: Histogram(durable_name,
|
||||
ranges,
|
||||
counts,
|
||||
logged_counts,
|
||||
meta,
|
||||
logged_meta) {}
|
||||
|
||||
std::string LinearHistogram::GetAsciiBucketRange(size_t i) const {
|
||||
int range = ranges(i);
|
||||
@ -1141,14 +1147,14 @@ HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) {
|
||||
}
|
||||
|
||||
std::unique_ptr<HistogramBase> BooleanHistogram::PersistentCreate(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta) {
|
||||
return WrapUnique(new BooleanHistogram(name, ranges, counts, logged_counts,
|
||||
meta, logged_meta));
|
||||
return WrapUnique(new BooleanHistogram(durable_name, ranges, counts,
|
||||
logged_counts, meta, logged_meta));
|
||||
}
|
||||
|
||||
HistogramType BooleanHistogram::GetHistogramType() const {
|
||||
@ -1161,17 +1167,23 @@ HistogramBase* BooleanHistogram::FactoryGetInternal(std::string_view name,
|
||||
return Factory(name, flags).Build();
|
||||
}
|
||||
|
||||
BooleanHistogram::BooleanHistogram(const char* name, const BucketRanges* ranges)
|
||||
: LinearHistogram(name, ranges) {}
|
||||
BooleanHistogram::BooleanHistogram(DurableStringView durable_name,
|
||||
const BucketRanges* ranges)
|
||||
: LinearHistogram(durable_name, ranges) {}
|
||||
|
||||
BooleanHistogram::BooleanHistogram(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta)
|
||||
: LinearHistogram(name, ranges, counts, logged_counts, meta, logged_meta) {}
|
||||
: LinearHistogram(durable_name,
|
||||
ranges,
|
||||
counts,
|
||||
logged_counts,
|
||||
meta,
|
||||
logged_meta) {}
|
||||
|
||||
HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) {
|
||||
std::string histogram_name;
|
||||
@ -1264,14 +1276,14 @@ HistogramBase* CustomHistogram::FactoryGet(
|
||||
}
|
||||
|
||||
std::unique_ptr<HistogramBase> CustomHistogram::PersistentCreate(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta) {
|
||||
return WrapUnique(new CustomHistogram(name, ranges, counts, logged_counts,
|
||||
meta, logged_meta));
|
||||
return WrapUnique(new CustomHistogram(durable_name, ranges, counts,
|
||||
logged_counts, meta, logged_meta));
|
||||
}
|
||||
|
||||
HistogramType CustomHistogram::GetHistogramType() const {
|
||||
@ -1292,17 +1304,23 @@ std::vector<Sample32> CustomHistogram::ArrayToCustomEnumRanges(
|
||||
return all_values;
|
||||
}
|
||||
|
||||
CustomHistogram::CustomHistogram(const char* name, const BucketRanges* ranges)
|
||||
: Histogram(name, ranges) {}
|
||||
CustomHistogram::CustomHistogram(DurableStringView durable_name,
|
||||
const BucketRanges* ranges)
|
||||
: Histogram(durable_name, ranges) {}
|
||||
|
||||
CustomHistogram::CustomHistogram(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta)
|
||||
: Histogram(name, ranges, counts, logged_counts, meta, logged_meta) {}
|
||||
: Histogram(durable_name,
|
||||
ranges,
|
||||
counts,
|
||||
logged_counts,
|
||||
meta,
|
||||
logged_meta) {}
|
||||
|
||||
void CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
|
||||
Histogram::SerializeInfoImpl(pickle);
|
||||
|
@ -176,7 +176,7 @@ class BASE_EXPORT Histogram : public HistogramBase {
|
||||
|
||||
// Create a histogram using data in persistent storage.
|
||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
@ -250,7 +250,7 @@ class BASE_EXPORT Histogram : public HistogramBase {
|
||||
|
||||
// |ranges| should contain the underflow and overflow buckets. See top
|
||||
// comments for example.
|
||||
Histogram(const char* name, const BucketRanges* ranges);
|
||||
Histogram(DurableStringView durable_name, const BucketRanges* ranges);
|
||||
|
||||
// Traditionally, histograms allocate their own memory for the bucket
|
||||
// vector but "shared" histograms use memory regions allocated from a
|
||||
@ -258,7 +258,7 @@ class BASE_EXPORT Histogram : public HistogramBase {
|
||||
// the life of this memory is managed externally and exceeds the lifetime
|
||||
// of this object. Practically, this memory is never released until the
|
||||
// process exits and the OS cleans it up.
|
||||
Histogram(const char* name,
|
||||
Histogram(DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
@ -383,7 +383,7 @@ class BASE_EXPORT LinearHistogram : public Histogram {
|
||||
|
||||
// Create a histogram using data in persistent storage.
|
||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
@ -418,9 +418,9 @@ class BASE_EXPORT LinearHistogram : public Histogram {
|
||||
protected:
|
||||
class Factory;
|
||||
|
||||
LinearHistogram(const char* name, const BucketRanges* ranges);
|
||||
LinearHistogram(DurableStringView durable_name, const BucketRanges* ranges);
|
||||
|
||||
LinearHistogram(const char* name,
|
||||
LinearHistogram(DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
@ -540,7 +540,7 @@ class BASE_EXPORT BooleanHistogram : public LinearHistogram {
|
||||
|
||||
// Create a histogram using data in persistent storage.
|
||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
@ -556,8 +556,8 @@ class BASE_EXPORT BooleanHistogram : public LinearHistogram {
|
||||
static HistogramBase* FactoryGetInternal(std::string_view name,
|
||||
int32_t flags);
|
||||
|
||||
BooleanHistogram(const char* name, const BucketRanges* ranges);
|
||||
BooleanHistogram(const char* name,
|
||||
BooleanHistogram(DurableStringView durable_name, const BucketRanges* ranges);
|
||||
BooleanHistogram(DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
@ -597,7 +597,7 @@ class BASE_EXPORT CustomHistogram : public Histogram {
|
||||
|
||||
// Create a histogram using data in persistent storage.
|
||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
@ -618,9 +618,9 @@ class BASE_EXPORT CustomHistogram : public Histogram {
|
||||
protected:
|
||||
class Factory;
|
||||
|
||||
CustomHistogram(const char* name, const BucketRanges* ranges);
|
||||
CustomHistogram(DurableStringView durable_name, const BucketRanges* ranges);
|
||||
|
||||
CustomHistogram(const char* name,
|
||||
CustomHistogram(DurableStringView durable_name,
|
||||
const BucketRanges* ranges,
|
||||
const DelayedPersistentAllocation& counts,
|
||||
const DelayedPersistentAllocation& logged_counts,
|
||||
|
@ -85,8 +85,12 @@ HistogramBase::CountAndBucketData& HistogramBase::CountAndBucketData::operator=(
|
||||
|
||||
const HistogramBase::Sample32 HistogramBase::kSampleType_MAX = INT_MAX;
|
||||
|
||||
HistogramBase::HistogramBase(const char* name)
|
||||
: histogram_name_(name), flags_(kNoFlags) {}
|
||||
HistogramBase::HistogramBase(DurableStringView name)
|
||||
: histogram_name_(name->data()),
|
||||
histogram_name_length_(base::saturated_cast<uint16_t>(name->length())),
|
||||
flags_(kNoFlags) {
|
||||
DCHECK_LT(name->length(), static_cast<size_t>(UINT16_MAX));
|
||||
}
|
||||
|
||||
HistogramBase::~HistogramBase() = default;
|
||||
|
||||
@ -97,14 +101,21 @@ void HistogramBase::CheckName(std::string_view name) const {
|
||||
}
|
||||
|
||||
void HistogramBase::SetFlags(int32_t flags) {
|
||||
flags_.fetch_or(flags, std::memory_order_relaxed);
|
||||
DCHECK_GE(flags, 0);
|
||||
DCHECK_LE(flags, static_cast<int32_t>(UINT16_MAX));
|
||||
CHECK_EQ(flags & ~0xFFFF, 0);
|
||||
flags_.fetch_or(static_cast<uint16_t>(flags), std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void HistogramBase::ClearFlags(int32_t flags) {
|
||||
flags_.fetch_and(~flags, std::memory_order_relaxed);
|
||||
DCHECK_GE(flags, 0);
|
||||
DCHECK_LE(flags, static_cast<int32_t>(UINT16_MAX));
|
||||
flags_.fetch_and(~static_cast<uint16_t>(flags), std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
bool HistogramBase::HasFlags(int32_t flags) const {
|
||||
DCHECK_GE(flags, 0);
|
||||
DCHECK_LE(flags, static_cast<int32_t>(UINT16_MAX));
|
||||
// Check this->flags() is a superset of |flags|, i.e. every flag in |flags| is
|
||||
// included.
|
||||
return (this->flags() & flags) == flags;
|
||||
@ -258,10 +269,12 @@ void HistogramBase::WriteAscii(std::string* output) const {
|
||||
}
|
||||
|
||||
// static
|
||||
char const* HistogramBase::GetPermanentName(std::string_view name) {
|
||||
// A set of histogram names that provides the "permanent" lifetime required
|
||||
// by histogram objects for those strings that are not already code constants
|
||||
// or held in persistent memory.
|
||||
DurableStringView HistogramBase::GetPermanentName(std::string_view name) {
|
||||
// A set of histogram names that provides the "permanent" lifetime required by
|
||||
// histogram objects for those strings that are not already code constants or
|
||||
// held in persistent memory. The container used for `permanent_names` MUST
|
||||
// support pointer-stability for its keys, due to small-string-optimization
|
||||
// in std::string.
|
||||
static base::NoDestructor<std::set<std::string, std::less<>>> permanent_names;
|
||||
static base::NoDestructor<Lock> permanent_names_lock;
|
||||
|
||||
@ -270,7 +283,7 @@ char const* HistogramBase::GetPermanentName(std::string_view name) {
|
||||
if (it == permanent_names->end() || *it != name) {
|
||||
it = permanent_names->emplace_hint(it, name);
|
||||
}
|
||||
return it->c_str();
|
||||
return DurableStringView(*it);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "base/atomicops.h"
|
||||
#include "base/base_export.h"
|
||||
#include "base/strings/durable_string_view.h"
|
||||
#include "base/time/time.h"
|
||||
#include "base/values.h"
|
||||
|
||||
@ -100,7 +101,7 @@ class BASE_EXPORT HistogramBase {
|
||||
|
||||
static const Sample32 kSampleType_MAX; // INT_MAX
|
||||
|
||||
enum Flags {
|
||||
enum Flags : uint16_t {
|
||||
kNoFlags = 0x0,
|
||||
|
||||
// Histogram should be UMA uploaded.
|
||||
@ -145,14 +146,16 @@ class BASE_EXPORT HistogramBase {
|
||||
|
||||
// Construct the base histogram. The name is not copied; it's up to the
|
||||
// caller to ensure that it lives at least as long as this object.
|
||||
explicit HistogramBase(const char* name);
|
||||
explicit HistogramBase(DurableStringView name);
|
||||
|
||||
HistogramBase(const HistogramBase&) = delete;
|
||||
HistogramBase& operator=(const HistogramBase&) = delete;
|
||||
|
||||
virtual ~HistogramBase();
|
||||
|
||||
const char* histogram_name() const { return histogram_name_; }
|
||||
std::string_view histogram_name() const {
|
||||
return {histogram_name_, histogram_name_length_};
|
||||
}
|
||||
|
||||
// Compares |name| to the histogram name and triggers a DCHECK if they do not
|
||||
// match. This is a helper function used by histogram macros, which results in
|
||||
@ -339,25 +342,28 @@ class BASE_EXPORT HistogramBase {
|
||||
// them passing |sample| as the parameter.
|
||||
void FindAndRunCallbacks(Sample32 sample) const;
|
||||
|
||||
// Gets a permanent string that can be used for histogram objects when the
|
||||
// original is not a code constant or held in persistent memory.
|
||||
static const char* GetPermanentName(std::string_view name);
|
||||
// Gets a view to a permanent string that can be used for histogram objects
|
||||
// when the original string is not a code constant or held in persistent
|
||||
// memory.
|
||||
static DurableStringView GetPermanentName(std::string_view name);
|
||||
|
||||
private:
|
||||
friend class HistogramBaseTest;
|
||||
friend class HistogramThreadsafeTest;
|
||||
|
||||
// A pointer to permanent storage where the histogram name is held. This can
|
||||
// be code space or the output of GetPermanentName() or any other storage
|
||||
// that is known to never change. This is not std::string_view because (a)
|
||||
// char* is 1/2 the size and (b) std::string_view transparently casts from
|
||||
// std::string which can easily lead to a pointer to non-permanent space. For
|
||||
// persistent histograms, this will simply point into the persistent memory
|
||||
// segment, thus avoiding duplication. For heap histograms, the
|
||||
// GetPermanentName method will create the necessary copy.
|
||||
// that is expected to never be deallocated or modified.
|
||||
const char* const histogram_name_;
|
||||
|
||||
// The length of the string pointed to by `histogram_name_`. This is stored
|
||||
// to avoid having to recalculate the length every time `histogram_name_` is
|
||||
// used and to avoid reading beyond the strings alloc in the event of memory
|
||||
// tampering or corruption.
|
||||
const uint16_t histogram_name_length_;
|
||||
|
||||
// Additional information about the histogram.
|
||||
std::atomic<int32_t> flags_{0};
|
||||
std::atomic<uint16_t> flags_{0};
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
|
@ -60,7 +60,7 @@ TEST_F(HistogramBaseTest, DeserializeHistogram) {
|
||||
deserialized = DeserializeHistogramInfo(&iter2);
|
||||
EXPECT_TRUE(deserialized);
|
||||
EXPECT_NE(histogram, deserialized);
|
||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_TRUE(deserialized->HasConstructionArguments(1, 1000, 10));
|
||||
|
||||
// kIPCSerializationSourceFlag will be cleared.
|
||||
@ -84,7 +84,7 @@ TEST_F(HistogramBaseTest, DeserializeLinearHistogram) {
|
||||
deserialized = DeserializeHistogramInfo(&iter2);
|
||||
EXPECT_TRUE(deserialized);
|
||||
EXPECT_NE(histogram, deserialized);
|
||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_TRUE(deserialized->HasConstructionArguments(1, 1000, 10));
|
||||
EXPECT_EQ(0, deserialized->flags());
|
||||
}
|
||||
@ -106,7 +106,7 @@ TEST_F(HistogramBaseTest, DeserializeBooleanHistogram) {
|
||||
deserialized = DeserializeHistogramInfo(&iter2);
|
||||
EXPECT_TRUE(deserialized);
|
||||
EXPECT_NE(histogram, deserialized);
|
||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_TRUE(deserialized->HasConstructionArguments(1, 2, 3));
|
||||
EXPECT_EQ(0, deserialized->flags());
|
||||
}
|
||||
@ -133,7 +133,7 @@ TEST_F(HistogramBaseTest, DeserializeCustomHistogram) {
|
||||
deserialized = DeserializeHistogramInfo(&iter2);
|
||||
EXPECT_TRUE(deserialized);
|
||||
EXPECT_NE(histogram, deserialized);
|
||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_TRUE(deserialized->HasConstructionArguments(5, 13, 4));
|
||||
EXPECT_EQ(0, deserialized->flags());
|
||||
}
|
||||
@ -155,7 +155,7 @@ TEST_F(HistogramBaseTest, DeserializeSparseHistogram) {
|
||||
deserialized = DeserializeHistogramInfo(&iter2);
|
||||
EXPECT_TRUE(deserialized);
|
||||
EXPECT_NE(histogram, deserialized);
|
||||
EXPECT_STREQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_EQ("TestHistogram", deserialized->histogram_name());
|
||||
EXPECT_EQ(0, deserialized->flags());
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/contains.h"
|
||||
#include "base/containers/map_util.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/metrics/histogram_delta_serialization.h"
|
||||
#include "base/metrics/histogram_functions.h"
|
||||
@ -48,7 +49,8 @@ class HistogramFlattenerDeltaRecorder : public HistogramFlattener {
|
||||
CHECK(!Contains(recorded_delta_histogram_sum_, histogram.histogram_name()));
|
||||
// Keep pointer to snapshot for testing. This really isn't ideal but the
|
||||
// snapshot-manager keeps the snapshot alive until it's "forgotten".
|
||||
recorded_delta_histogram_sum_[histogram.histogram_name()] = snapshot.sum();
|
||||
InsertOrAssign(recorded_delta_histogram_sum_, histogram.histogram_name(),
|
||||
snapshot.sum());
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
@ -69,7 +71,7 @@ class HistogramFlattenerDeltaRecorder : public HistogramFlattener {
|
||||
private:
|
||||
std::vector<raw_ptr<const HistogramBase, VectorExperimental>>
|
||||
recorded_delta_histograms_;
|
||||
std::map<std::string, int64_t> recorded_delta_histogram_sum_;
|
||||
std::map<std::string, int64_t, std::less<>> recorded_delta_histogram_sum_;
|
||||
};
|
||||
|
||||
class HistogramSnapshotManagerTest : public testing::Test {
|
||||
|
@ -9,11 +9,11 @@
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/atomicops.h"
|
||||
#include "base/containers/contains.h"
|
||||
#include "base/containers/span.h"
|
||||
#include "base/memory/raw_span.h"
|
||||
#include "base/metrics/bucket_ranges.h"
|
||||
@ -31,16 +31,6 @@ namespace base {
|
||||
|
||||
namespace {
|
||||
|
||||
char const* GetPermanentName(const std::string& name) {
|
||||
// A set of histogram names that provides the "permanent" lifetime required
|
||||
// by histogram objects for those strings that are not already code constants
|
||||
// or held in persistent memory.
|
||||
static base::NoDestructor<std::set<std::string>> permanent_names;
|
||||
|
||||
auto result = permanent_names->insert(name);
|
||||
return result.first->c_str();
|
||||
}
|
||||
|
||||
size_t GetBucketIndex(HistogramBase::Sample32 value, const BucketRanges* ranges) {
|
||||
size_t bucket_count = ranges->bucket_count();
|
||||
EXPECT_GE(bucket_count, 1U);
|
||||
@ -235,15 +225,15 @@ class HistogramThreadsafeTest : public testing::Test {
|
||||
// during the test.
|
||||
std::string local_heap_histogram_name =
|
||||
StringPrintf("LocalHeapNumericHistogram%zu", suffix);
|
||||
auto& local_heap_histogram = histograms_.emplace_back(
|
||||
new Histogram(GetPermanentName(local_heap_histogram_name),
|
||||
numeric_histogram->bucket_ranges()));
|
||||
auto& local_heap_histogram = histograms_.emplace_back(new Histogram(
|
||||
HistogramBase::GetPermanentName(local_heap_histogram_name),
|
||||
numeric_histogram->bucket_ranges()));
|
||||
histograms.push_back(local_heap_histogram.get());
|
||||
std::string local_heap_sparse_histogram_name =
|
||||
StringPrintf("LocalHeapSparseHistogram%zu", suffix);
|
||||
auto& local_heap_sparse_histogram =
|
||||
histograms_.emplace_back(new SparseHistogram(
|
||||
GetPermanentName(local_heap_sparse_histogram_name)));
|
||||
HistogramBase::GetPermanentName(local_heap_sparse_histogram_name)));
|
||||
histograms.push_back(local_heap_sparse_histogram.get());
|
||||
|
||||
// Furthermore, create two additional *different* histogram objects that
|
||||
@ -446,7 +436,7 @@ TEST_F(HistogramThreadsafeTest, SnapshotDeltaThreadsafe) {
|
||||
// a normal histogram, once as a simulation of a subprocess histogram, and
|
||||
// once as a duplicate histogram created from the same allocator.
|
||||
size_t expected_logged_samples_count = kNumThreads * kNumEmissions;
|
||||
if (!strstr(histogram->histogram_name(), "LocalHeap")) {
|
||||
if (!Contains(histogram->histogram_name(), "LocalHeap")) {
|
||||
expected_logged_samples_count *= 3;
|
||||
}
|
||||
ASSERT_EQ(static_cast<size_t>(logged_samples->TotalCount()),
|
||||
|
@ -324,14 +324,17 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
|
||||
PersistentHistogramData* data =
|
||||
memory_allocator_->GetAsObject<PersistentHistogramData>(ref, &alloc_size);
|
||||
|
||||
// Get a bounded view of the metric name. Note that this is a durable but
|
||||
// volatile view. I.e., the data lives in the persistent shared memory region
|
||||
// and will not be freed, but the contents of the view may change at any time.
|
||||
// Checks data for nullptr; `metric_name` not empty means data is not nullptr.
|
||||
std::string_view metric_name = PersistentMemoryAllocator::StringViewAt(
|
||||
data, offsetof(PersistentHistogramData, name), alloc_size);
|
||||
DurableStringView durable_metric_name(PersistentMemoryAllocator::StringViewAt(
|
||||
data, offsetof(PersistentHistogramData, name), alloc_size));
|
||||
|
||||
// Check that metadata is reasonable: metric_name is non-empty,
|
||||
// ID fields have been loaded with a hash of the name (0 is considered
|
||||
// unset/invalid).
|
||||
if (metric_name.empty() ||
|
||||
if (durable_metric_name->empty() ||
|
||||
UNSAFE_TODO(reinterpret_cast<const char*>(data)[alloc_size - 1]) !=
|
||||
'\0' ||
|
||||
data->samples_metadata.id == 0 || data->logged_metadata.id == 0 ||
|
||||
@ -342,10 +345,10 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
|
||||
// could just verify the name length based on the overall alloc length,
|
||||
// but that doesn't work because the allocated block may have been
|
||||
// aligned to the next boundary value.
|
||||
HashMetricName(metric_name) != data->samples_metadata.id) {
|
||||
HashMetricName(*durable_metric_name) != data->samples_metadata.id) {
|
||||
return nullptr;
|
||||
}
|
||||
return CreateHistogram(data);
|
||||
return CreateHistogram(data, durable_metric_name);
|
||||
}
|
||||
|
||||
std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
|
||||
@ -456,7 +459,10 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
|
||||
// using what is already known above but avoids duplicating the switch
|
||||
// statement here and serves as a double-check that everything is
|
||||
// correct before commiting the new histogram to persistent space.
|
||||
std::unique_ptr<HistogramBase> histogram = CreateHistogram(histogram_data);
|
||||
DurableStringView durable_name(
|
||||
std::string_view(histogram_data->name, name.size()));
|
||||
std::unique_ptr<HistogramBase> histogram =
|
||||
CreateHistogram(histogram_data, durable_name);
|
||||
DCHECK(histogram);
|
||||
DCHECK_NE(0U, histogram_data->samples_metadata.id);
|
||||
DCHECK_NE(0U, histogram_data->logged_metadata.id);
|
||||
@ -566,15 +572,20 @@ void PersistentHistogramAllocator::ClearLastCreatedReferenceForTesting() {
|
||||
}
|
||||
|
||||
std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
|
||||
PersistentHistogramData* histogram_data_ptr) {
|
||||
PersistentHistogramData* histogram_data_ptr,
|
||||
DurableStringView durable_name) {
|
||||
if (!histogram_data_ptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The durable name is expected to be hanging off the end of the histogram
|
||||
// data (which we expect was allocated by the persistent memory allocator).
|
||||
DCHECK_EQ(durable_name->data(), histogram_data_ptr->name);
|
||||
|
||||
// Sparse histograms are quite different so handle them as a special case.
|
||||
if (histogram_data_ptr->histogram_type == SPARSE_HISTOGRAM) {
|
||||
std::unique_ptr<HistogramBase> histogram =
|
||||
SparseHistogram::PersistentCreate(this, histogram_data_ptr->name,
|
||||
SparseHistogram::PersistentCreate(this, durable_name,
|
||||
&histogram_data_ptr->samples_metadata,
|
||||
&histogram_data_ptr->logged_metadata);
|
||||
DCHECK(histogram);
|
||||
@ -662,33 +673,32 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
|
||||
kTypeIdCountsArray, counts_bytes, counts_bytes / 2);
|
||||
|
||||
// Create the right type of histogram.
|
||||
const char* name = histogram_data_ptr->name;
|
||||
std::unique_ptr<HistogramBase> histogram;
|
||||
switch (histogram_type) {
|
||||
case HISTOGRAM:
|
||||
histogram =
|
||||
Histogram::PersistentCreate(name, ranges, counts_data, logged_data,
|
||||
&histogram_data_ptr->samples_metadata,
|
||||
&histogram_data_ptr->logged_metadata);
|
||||
histogram = Histogram::PersistentCreate(
|
||||
durable_name, ranges, counts_data, logged_data,
|
||||
&histogram_data_ptr->samples_metadata,
|
||||
&histogram_data_ptr->logged_metadata);
|
||||
DCHECK(histogram);
|
||||
break;
|
||||
case LINEAR_HISTOGRAM:
|
||||
histogram = LinearHistogram::PersistentCreate(
|
||||
name, ranges, counts_data, logged_data,
|
||||
durable_name, ranges, counts_data, logged_data,
|
||||
&histogram_data_ptr->samples_metadata,
|
||||
&histogram_data_ptr->logged_metadata);
|
||||
DCHECK(histogram);
|
||||
break;
|
||||
case BOOLEAN_HISTOGRAM:
|
||||
histogram = BooleanHistogram::PersistentCreate(
|
||||
name, ranges, counts_data, logged_data,
|
||||
durable_name, ranges, counts_data, logged_data,
|
||||
&histogram_data_ptr->samples_metadata,
|
||||
&histogram_data_ptr->logged_metadata);
|
||||
DCHECK(histogram);
|
||||
break;
|
||||
case CUSTOM_HISTOGRAM:
|
||||
histogram = CustomHistogram::PersistentCreate(
|
||||
name, ranges, counts_data, logged_data,
|
||||
durable_name, ranges, counts_data, logged_data,
|
||||
&histogram_data_ptr->samples_metadata,
|
||||
&histogram_data_ptr->logged_metadata);
|
||||
DCHECK(histogram);
|
||||
|
@ -334,8 +334,13 @@ class BASE_EXPORT PersistentHistogramAllocator {
|
||||
|
||||
private:
|
||||
// Create a histogram based on saved (persistent) information about it.
|
||||
// `histogram_data_ptr` refers to a variable length structure, ending
|
||||
// with the histogram name. `durable_name` must be a durable string view
|
||||
// starting at `histogram_data_ptr->name` and with some length bounded by the
|
||||
// `alloc_size` returned from the `memory_allocator`.
|
||||
std::unique_ptr<HistogramBase> CreateHistogram(
|
||||
PersistentHistogramData* histogram_data_ptr);
|
||||
PersistentHistogramData* histogram_data_ptr,
|
||||
DurableStringView durable_name);
|
||||
|
||||
// Gets or creates an object in the global StatisticsRecorder matching
|
||||
// the `histogram` passed. Null is returned if one was not found and
|
||||
|
@ -686,7 +686,7 @@ TEST_F(PersistentHistogramAllocatorTest, MovePersistentFile) {
|
||||
std::unique_ptr<HistogramBase> histogram;
|
||||
bool found_histogram = false;
|
||||
while ((histogram = it.GetNext()) != nullptr) {
|
||||
if (strcmp(kHistogramName, histogram->histogram_name()) == 0) {
|
||||
if (histogram->histogram_name() == kHistogramName) {
|
||||
found_histogram = true;
|
||||
break;
|
||||
}
|
||||
|
@ -89,10 +89,11 @@ HistogramBase* SparseHistogram::FactoryGet(std::string_view name,
|
||||
// static
|
||||
std::unique_ptr<HistogramBase> SparseHistogram::PersistentCreate(
|
||||
PersistentHistogramAllocator* allocator,
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta) {
|
||||
return WrapUnique(new SparseHistogram(allocator, name, meta, logged_meta));
|
||||
return WrapUnique(
|
||||
new SparseHistogram(allocator, durable_name, meta, logged_meta));
|
||||
}
|
||||
|
||||
SparseHistogram::~SparseHistogram() = default;
|
||||
@ -200,16 +201,16 @@ void SparseHistogram::SerializeInfoImpl(Pickle* pickle) const {
|
||||
pickle->WriteInt(flags());
|
||||
}
|
||||
|
||||
SparseHistogram::SparseHistogram(const char* name)
|
||||
: HistogramBase(name),
|
||||
unlogged_samples_(new SampleMap(HashMetricName(name))),
|
||||
SparseHistogram::SparseHistogram(DurableStringView durable_name)
|
||||
: HistogramBase(durable_name),
|
||||
unlogged_samples_(new SampleMap(HashMetricName(*durable_name))),
|
||||
logged_samples_(new SampleMap(unlogged_samples_->id())) {}
|
||||
|
||||
SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator,
|
||||
const char* name,
|
||||
DurableStringView durable_name,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta)
|
||||
: HistogramBase(name),
|
||||
: HistogramBase(durable_name),
|
||||
// While other histogram types maintain a static vector of values with
|
||||
// sufficient space for both "active" and "logged" samples, with each
|
||||
// SampleVector being given the appropriate half, sparse histograms
|
||||
@ -220,8 +221,9 @@ SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator,
|
||||
// "active" samples use, for convenience purposes, an ID matching
|
||||
// that of the histogram while the "logged" samples use that number
|
||||
// plus 1.
|
||||
unlogged_samples_(
|
||||
new PersistentSampleMap(HashMetricName(name), allocator, meta)),
|
||||
unlogged_samples_(new PersistentSampleMap(HashMetricName(*durable_name),
|
||||
allocator,
|
||||
meta)),
|
||||
logged_samples_(new PersistentSampleMap(unlogged_samples_->id() + 1,
|
||||
allocator,
|
||||
logged_meta)) {}
|
||||
|
@ -35,7 +35,7 @@ class BASE_EXPORT SparseHistogram : public HistogramBase {
|
||||
// live longer than the created sparse histogram.
|
||||
static std::unique_ptr<HistogramBase> PersistentCreate(
|
||||
PersistentHistogramAllocator* allocator,
|
||||
const char* name,
|
||||
DurableStringView name,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta);
|
||||
|
||||
@ -67,10 +67,10 @@ class BASE_EXPORT SparseHistogram : public HistogramBase {
|
||||
|
||||
private:
|
||||
// Clients should always use FactoryGet to create SparseHistogram.
|
||||
explicit SparseHistogram(const char* name);
|
||||
explicit SparseHistogram(DurableStringView name);
|
||||
|
||||
SparseHistogram(PersistentHistogramAllocator* allocator,
|
||||
const char* name,
|
||||
DurableStringView name,
|
||||
HistogramSamples::Metadata* meta,
|
||||
HistogramSamples::Metadata* logged_meta);
|
||||
|
||||
|
@ -78,10 +78,12 @@ class SparseHistogramTest : public testing::TestWithParam<bool> {
|
||||
GlobalHistogramAllocator::ReleaseForTesting();
|
||||
}
|
||||
|
||||
std::unique_ptr<SparseHistogram> NewSparseHistogram(const char* name) {
|
||||
template <size_t N>
|
||||
std::unique_ptr<SparseHistogram> NewSparseHistogram(const char (&name)[N]) {
|
||||
// std::make_unique can't access protected ctor so do it manually. This
|
||||
// test class is a friend so can access it.
|
||||
return std::unique_ptr<SparseHistogram>(new SparseHistogram(name));
|
||||
return std::unique_ptr<SparseHistogram>(
|
||||
new SparseHistogram(DurableStringView(std::string_view(name, N - 1))));
|
||||
}
|
||||
|
||||
CountAndBucketData GetCountAndBucketData(SparseHistogram* histogram) {
|
||||
@ -268,7 +270,7 @@ TEST_P(SparseHistogramTest, MacroBasicTest) {
|
||||
const HistogramBase* const sparse_histogram = histograms[0];
|
||||
|
||||
EXPECT_EQ(SPARSE_HISTOGRAM, sparse_histogram->GetHistogramType());
|
||||
EXPECT_STREQ("Sparse", sparse_histogram->histogram_name());
|
||||
EXPECT_EQ("Sparse", sparse_histogram->histogram_name());
|
||||
EXPECT_EQ(
|
||||
HistogramBase::kUmaTargetedHistogramFlag |
|
||||
(use_persistent_histogram_allocator_ ? HistogramBase::kIsPersistent
|
||||
@ -292,8 +294,8 @@ TEST_P(SparseHistogramTest, MacroInLoopTest) {
|
||||
const StatisticsRecorder::Histograms histograms =
|
||||
StatisticsRecorder::Sort(StatisticsRecorder::GetHistograms());
|
||||
ASSERT_THAT(histograms, testing::SizeIs(2));
|
||||
EXPECT_STREQ(histograms[0]->histogram_name(), "Sparse0");
|
||||
EXPECT_STREQ(histograms[1]->histogram_name(), "Sparse1");
|
||||
EXPECT_EQ(histograms[0]->histogram_name(), "Sparse0");
|
||||
EXPECT_EQ(histograms[1]->histogram_name(), "Sparse1");
|
||||
}
|
||||
|
||||
TEST_P(SparseHistogramTest, Serialize) {
|
||||
|
@ -34,7 +34,7 @@ namespace {
|
||||
|
||||
bool HistogramNameLesser(const base::HistogramBase* a,
|
||||
const base::HistogramBase* b) {
|
||||
return strcmp(a->histogram_name(), b->histogram_name()) < 0;
|
||||
return a->histogram_name() < b->histogram_name();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -56,7 +56,7 @@ std::atomic<StatisticsRecorder::GlobalSampleCallback>
|
||||
StatisticsRecorder::global_sample_callback_{nullptr};
|
||||
|
||||
StatisticsRecorder::ScopedHistogramSampleObserver::
|
||||
ScopedHistogramSampleObserver(const std::string& name,
|
||||
ScopedHistogramSampleObserver(std::string_view name,
|
||||
OnSampleCallback callback)
|
||||
: histogram_name_(name), callback_(callback) {
|
||||
StatisticsRecorder::AddHistogramSampleObserver(histogram_name_, this);
|
||||
@ -68,7 +68,7 @@ StatisticsRecorder::ScopedHistogramSampleObserver::
|
||||
}
|
||||
|
||||
void StatisticsRecorder::ScopedHistogramSampleObserver::RunCallback(
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
HistogramBase::Sample32 sample) {
|
||||
callback_.Run(histogram_name, name_hash, sample);
|
||||
@ -144,8 +144,7 @@ HistogramBase* StatisticsRecorder::RegisterOrDeleteDuplicate(
|
||||
// you are unluckily a victim of a hash collision. For now, the best solution
|
||||
// is to rename the histogram. Reach out to chrome-metrics-team@google.com if
|
||||
// you are unsure!
|
||||
DCHECK_EQ(strcmp(histogram->histogram_name(), registered->histogram_name()),
|
||||
0)
|
||||
DCHECK_EQ(histogram->histogram_name(), registered->histogram_name())
|
||||
<< "Histogram name hash collision between " << histogram->histogram_name()
|
||||
<< " and " << registered->histogram_name() << " (hash = " << hash << ")";
|
||||
|
||||
@ -385,7 +384,7 @@ void StatisticsRecorder::RemoveHistogramSampleObserver(
|
||||
// static
|
||||
void StatisticsRecorder::FindAndRunHistogramCallbacks(
|
||||
base::PassKey<HistogramBase>,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
HistogramBase::Sample32 sample) {
|
||||
DCHECK_EQ(name_hash, HashMetricName(histogram_name));
|
||||
@ -530,26 +529,26 @@ StatisticsRecorder::Histograms StatisticsRecorder::Sort(Histograms histograms) {
|
||||
// static
|
||||
StatisticsRecorder::Histograms StatisticsRecorder::WithName(
|
||||
Histograms histograms,
|
||||
const std::string& query,
|
||||
std::string_view query,
|
||||
bool case_sensitive) {
|
||||
// Need a C-string query for comparisons against C-string histogram name.
|
||||
std::string lowercase_query;
|
||||
const char* query_string;
|
||||
if (case_sensitive) {
|
||||
query_string = query.c_str();
|
||||
} else {
|
||||
lowercase_query = base::ToLowerASCII(query);
|
||||
query_string = lowercase_query.c_str();
|
||||
}
|
||||
|
||||
auto removed = std::ranges::remove_if(
|
||||
histograms, [query_string, case_sensitive](const HistogramBase* const h) {
|
||||
return !strstr(case_sensitive
|
||||
? h->histogram_name()
|
||||
: base::ToLowerASCII(h->histogram_name()).c_str(),
|
||||
query_string);
|
||||
});
|
||||
histograms.erase(removed.begin(), removed.end());
|
||||
// Char equality comparator which respects the `case_sensitive` setting.
|
||||
auto comparator = [case_sensitive](char a, char b) {
|
||||
return case_sensitive ? a == b : std::toupper(a) == std::toupper(b);
|
||||
};
|
||||
// Filter function that returns true if `h->histogram_name()` does not contain
|
||||
// `query`. Uses `comparator` to compare chars.
|
||||
auto histogram_name_does_not_contain_query =
|
||||
[comparator, query](const HistogramBase* const h) {
|
||||
const auto& name = h->histogram_name();
|
||||
return std::search(name.begin(), name.end(), query.begin(), query.end(),
|
||||
comparator) == name.end();
|
||||
};
|
||||
// Erase the non-matching histograms. Note that `histograms` was passed by
|
||||
// value so we can efficiently remove the unwanted elements and return the
|
||||
// local instance.
|
||||
histograms.erase(std::remove_if(histograms.begin(), histograms.end(),
|
||||
histogram_name_does_not_contain_query),
|
||||
histograms.end());
|
||||
return histograms;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ class BASE_EXPORT StatisticsRecorder {
|
||||
// about a histogram sample. This is used in conjunction with
|
||||
// ScopedHistogramSampleObserver to get notified when a sample is collected.
|
||||
using OnSampleCallback =
|
||||
base::RepeatingCallback<void(const char* /*=histogram_name*/,
|
||||
base::RepeatingCallback<void(std::string_view /*=histogram_name*/,
|
||||
uint64_t /*=name_hash*/,
|
||||
HistogramBase::Sample32)>;
|
||||
|
||||
@ -89,7 +89,7 @@ class BASE_EXPORT StatisticsRecorder {
|
||||
public:
|
||||
// Constructor. Called with the desired histogram name and the callback to
|
||||
// be invoked when a sample is recorded.
|
||||
explicit ScopedHistogramSampleObserver(const std::string& histogram_name,
|
||||
explicit ScopedHistogramSampleObserver(std::string_view histogram_name,
|
||||
OnSampleCallback callback);
|
||||
~ScopedHistogramSampleObserver();
|
||||
|
||||
@ -97,7 +97,7 @@ class BASE_EXPORT StatisticsRecorder {
|
||||
friend class StatisticsRecorder;
|
||||
|
||||
// Runs the callback.
|
||||
void RunCallback(const char* histogram_name,
|
||||
void RunCallback(std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
HistogramBase::Sample32 sample);
|
||||
|
||||
@ -216,7 +216,7 @@ class BASE_EXPORT StatisticsRecorder {
|
||||
//
|
||||
// This method is thread safe.
|
||||
static void FindAndRunHistogramCallbacks(base::PassKey<HistogramBase>,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
HistogramBase::Sample32 sample);
|
||||
|
||||
@ -275,10 +275,10 @@ class BASE_EXPORT StatisticsRecorder {
|
||||
// |case_sensitive| determines whether the matching should be done in a
|
||||
// case sensitive way.
|
||||
static Histograms WithName(Histograms histograms,
|
||||
const std::string& query,
|
||||
std::string_view query,
|
||||
bool case_sensitive = true);
|
||||
|
||||
using GlobalSampleCallback = void (*)(const char* /*=histogram_name*/,
|
||||
using GlobalSampleCallback = void (*)(std::string_view /*=histogram_name*/,
|
||||
uint64_t /*=name_hash*/,
|
||||
HistogramBase::Sample32);
|
||||
// Installs a global callback which will be called for every added
|
||||
|
@ -121,7 +121,7 @@ class StatisticsRecorderTest : public testing::TestWithParam<bool> {
|
||||
return StatisticsRecorder::top_ != nullptr;
|
||||
}
|
||||
|
||||
Histogram* CreateHistogram(const char* name,
|
||||
Histogram* CreateHistogram(DurableStringView durable_name,
|
||||
HistogramBase::Sample32 min,
|
||||
HistogramBase::Sample32 max,
|
||||
size_t bucket_count) {
|
||||
@ -129,7 +129,16 @@ class StatisticsRecorderTest : public testing::TestWithParam<bool> {
|
||||
Histogram::InitializeBucketRanges(min, max, ranges);
|
||||
const BucketRanges* registered_ranges =
|
||||
StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
|
||||
return new Histogram(name, registered_ranges);
|
||||
return new Histogram(durable_name, registered_ranges);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
Histogram* CreateHistogram(const char (&literal)[N],
|
||||
HistogramBase::Sample32 min,
|
||||
HistogramBase::Sample32 max,
|
||||
size_t bucket_count) {
|
||||
return CreateHistogram(DurableStringView(std::string_view(literal, N - 1)),
|
||||
min, max, bucket_count);
|
||||
}
|
||||
|
||||
void InitLogOnShutdown() { StatisticsRecorder::InitLogOnShutdown(); }
|
||||
@ -459,17 +468,17 @@ namespace {
|
||||
struct CallbackCheckWrapper {
|
||||
CallbackCheckWrapper() : last_name_hash(HashMetricName("")) {}
|
||||
|
||||
void OnHistogramChanged(const char* histogram_name,
|
||||
void OnHistogramChanged(std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
HistogramBase::Sample32 histogram_value) {
|
||||
called = true;
|
||||
last_histogram_name = histogram_name;
|
||||
last_histogram_name = std::string(histogram_name);
|
||||
last_name_hash = name_hash;
|
||||
last_histogram_value = histogram_value;
|
||||
}
|
||||
|
||||
bool called = false;
|
||||
const char* last_histogram_name = "";
|
||||
std::string last_histogram_name = "";
|
||||
uint64_t last_name_hash;
|
||||
base::HistogramBase::Sample32 last_histogram_value = 0;
|
||||
};
|
||||
@ -479,7 +488,7 @@ struct CallbackCheckWrapper {
|
||||
TEST_P(StatisticsRecorderTest,
|
||||
AddHistogramCallbackBeforeHistogramRegistration) {
|
||||
test::TaskEnvironment task_environment;
|
||||
const char* histogram_name = "TestHistogram";
|
||||
constexpr char histogram_name[] = "TestHistogram";
|
||||
CallbackCheckWrapper callback_wrapper;
|
||||
|
||||
auto callback =
|
||||
@ -500,7 +509,7 @@ TEST_P(StatisticsRecorderTest,
|
||||
TEST_P(StatisticsRecorderTest,
|
||||
RemoveHistogramCallbackBeforeHistogramRegistrationWithMultipleClients) {
|
||||
test::TaskEnvironment task_environment;
|
||||
const char* histogram_name = "TestHistogram";
|
||||
constexpr char histogram_name[] = "TestHistogram";
|
||||
CallbackCheckWrapper callback_wrapper1;
|
||||
CallbackCheckWrapper callback_wrapper2;
|
||||
|
||||
@ -623,7 +632,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedTest) {
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
EXPECT_TRUE(callback_wrapper.called);
|
||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_name_hash, HashMetricName("TestHistogram"));
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||
}
|
||||
@ -644,7 +653,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedTest) {
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
EXPECT_TRUE(callback_wrapper.called);
|
||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestLinearHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestLinearHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_name_hash,
|
||||
HashMetricName("TestLinearHistogram"));
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||
@ -669,7 +678,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedTest) {
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
EXPECT_TRUE(callback_wrapper.called);
|
||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestCustomHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestCustomHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_name_hash,
|
||||
HashMetricName("TestCustomHistogram"));
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||
@ -691,7 +700,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedTest) {
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
EXPECT_TRUE(callback_wrapper.called);
|
||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestSparseHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestSparseHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_name_hash,
|
||||
HashMetricName("TestSparseHistogram"));
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||
@ -716,7 +725,7 @@ TEST_P(StatisticsRecorderTest, CallbackUsedBeforeHistogramCreatedTest) {
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
EXPECT_TRUE(callback_wrapper.called);
|
||||
EXPECT_STREQ(callback_wrapper.last_histogram_name, "TestHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_name, "TestHistogram");
|
||||
EXPECT_EQ(callback_wrapper.last_name_hash, HashMetricName("TestHistogram"));
|
||||
EXPECT_EQ(callback_wrapper.last_histogram_value, 1);
|
||||
}
|
||||
@ -731,9 +740,9 @@ TEST_P(StatisticsRecorderTest, GlobalCallbackCalled) {
|
||||
// function pointer.
|
||||
static size_t callback_callcount;
|
||||
callback_callcount = 0;
|
||||
auto callback = [](const char* histogram_name, uint64_t name_hash,
|
||||
auto callback = [](std::string_view histogram_name, uint64_t name_hash,
|
||||
HistogramBase::Sample32 sample) {
|
||||
EXPECT_STREQ(histogram_name, "TestHistogram");
|
||||
EXPECT_EQ(histogram_name, "TestHistogram");
|
||||
EXPECT_EQ(sample, 1);
|
||||
++callback_callcount;
|
||||
};
|
||||
|
25
base/strings/durable_string_view.h
Normal file
25
base/strings/durable_string_view.h
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2025 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
#ifndef BASE_STRINGS_DURABLE_STRING_VIEW_H_
|
||||
#define BASE_STRINGS_DURABLE_STRING_VIEW_H_
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "base/types/strong_alias.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
// A strong type alias which denotes a std::string_view having durable storage.
|
||||
// This allows the programmer to declare that a particular string_view is over
|
||||
// memory that will not be deallocated. I.e., the programmer's use of this alias
|
||||
// is a promise that it is safe to read from within the memory bounds.
|
||||
//
|
||||
// While the underlying string view data can and should be considered const,
|
||||
// note that DurableStringView is unable to *guarantee* that underlying data
|
||||
// is truly const.
|
||||
using DurableStringView = base::StrongAlias<class DurableTag, std::string_view>;
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BASE_STRINGS_DURABLE_STRING_VIEW_H_
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "base/containers/map_util.h"
|
||||
#include "base/metrics/histogram.h"
|
||||
#include "base/metrics/histogram_samples.h"
|
||||
#include "base/metrics/metrics_hashes.h"
|
||||
@ -24,8 +25,8 @@ HistogramTester::HistogramTester() {
|
||||
// Record any histogram data that exists when the object is created so it can
|
||||
// be subtracted later.
|
||||
for (const auto* const histogram : StatisticsRecorder::GetHistograms()) {
|
||||
histograms_snapshot_[histogram->histogram_name()] =
|
||||
histogram->SnapshotSamples();
|
||||
InsertOrAssign(histograms_snapshot_, histogram->histogram_name(),
|
||||
histogram->SnapshotSamples());
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,7 +206,8 @@ HistogramTester::CountsMap HistogramTester::GetTotalCountsForPrefix(
|
||||
GetHistogramSamplesSinceCreation(histogram->histogram_name());
|
||||
// Omit unchanged histograms from the result.
|
||||
if (new_samples->TotalCount()) {
|
||||
result[histogram->histogram_name()] = new_samples->TotalCount();
|
||||
InsertOrAssign(result, histogram->histogram_name(),
|
||||
new_samples->TotalCount());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -77,7 +77,7 @@ size_t ExtensionConsoleErrorObserver::GetErrorsAndWarningsCount() const {
|
||||
return errors_.size();
|
||||
}
|
||||
|
||||
HistogramWaiter::HistogramWaiter(const char* metric_name) {
|
||||
HistogramWaiter::HistogramWaiter(std::string_view metric_name) {
|
||||
histogram_observer_ =
|
||||
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||
metric_name,
|
||||
@ -93,9 +93,10 @@ void HistogramWaiter::Wait() {
|
||||
run_loop_.Run();
|
||||
}
|
||||
|
||||
void HistogramWaiter::OnHistogramCallback(const char* metric_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) {
|
||||
void HistogramWaiter::OnHistogramCallback(
|
||||
std::string_view metric_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) {
|
||||
run_loop_.Quit();
|
||||
histogram_observer_.reset();
|
||||
}
|
||||
|
@ -103,14 +103,14 @@ class ExtensionConsoleErrorObserver : public ErrorConsole::Observer {
|
||||
// times, create multiple instances of this class.
|
||||
class HistogramWaiter {
|
||||
public:
|
||||
explicit HistogramWaiter(const char* metric_name);
|
||||
explicit HistogramWaiter(std::string_view metric_name);
|
||||
~HistogramWaiter();
|
||||
HistogramWaiter(const HistogramWaiter&) = delete;
|
||||
HistogramWaiter& operator=(const HistogramWaiter&) = delete;
|
||||
|
||||
// Waits for the next update to the observed histogram.
|
||||
void Wait();
|
||||
void OnHistogramCallback(const char* metric_name,
|
||||
void OnHistogramCallback(std::string_view metric_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample);
|
||||
|
||||
|
@ -195,9 +195,9 @@ class MetricsScraper {
|
||||
std::vector<std::string> histogram_names;
|
||||
for (base::HistogramBase* histogram :
|
||||
base::StatisticsRecorder::GetHistograms()) {
|
||||
const std::string& name = histogram->histogram_name();
|
||||
const auto& name = histogram->histogram_name();
|
||||
if (MatchesRegex(base::UTF8ToUTF16(name), *histogram_regex_)) {
|
||||
histogram_names.push_back(name);
|
||||
histogram_names.emplace_back(name);
|
||||
}
|
||||
}
|
||||
std::ranges::sort(histogram_names);
|
||||
|
@ -87,7 +87,7 @@ IN_PROC_BROWSER_TEST_F(StartupMetricsTest, MAYBE_ReportsValues) {
|
||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||
histogram,
|
||||
base::BindLambdaForTesting(
|
||||
[&](const char* histogram_name, uint64_t name_hash,
|
||||
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||
run_loop.Run();
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ class NotificationPlatformBridgeWinUITest : public InProcessBrowserTest {
|
||||
}
|
||||
|
||||
void OnHistogramRecorded(const base::RepeatingClosure& quit_closure,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) {
|
||||
quit_closure.Run();
|
||||
|
@ -67,7 +67,7 @@ void WaitForHistogram(const std::string& histogram_name) {
|
||||
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||
histogram_name,
|
||||
base::BindLambdaForTesting(
|
||||
[&](const char* histogram_name, uint64_t name_hash,
|
||||
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||
run_loop.Run();
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ class PasswordManagerAndroidBrowserTest
|
||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||
histogram_name,
|
||||
base::BindLambdaForTesting(
|
||||
[&](const char* histogram_name, uint64_t name_hash,
|
||||
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||
run_loop.Run();
|
||||
}
|
||||
|
@ -926,7 +926,7 @@ class
|
||||
/*disabled_features=*/{});
|
||||
}
|
||||
|
||||
size_t GetTotalSampleCount(const std::string& histogram_name) {
|
||||
size_t GetTotalSampleCount(std::string_view histogram_name) {
|
||||
auto buckets = histogram_tester_.GetAllSamples(histogram_name);
|
||||
size_t count = 0;
|
||||
for (const auto& bucket : buckets) {
|
||||
@ -949,7 +949,7 @@ class
|
||||
auto histogram_observer = std::make_unique<
|
||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||
histogram_name,
|
||||
base::BindLambdaForTesting([&](const char* histogram_name,
|
||||
base::BindLambdaForTesting([&](std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) {
|
||||
if (GetTotalSampleCount(histogram_name) >= expected_sample_count) {
|
||||
|
@ -275,7 +275,7 @@ class SegmentationPlatformTest : public PlatformBrowserTest {
|
||||
return search_user_metadata;
|
||||
}
|
||||
|
||||
void WaitForHistogram(const std::string& histogram_name,
|
||||
void WaitForHistogram(std::string_view histogram_name,
|
||||
const base::HistogramTester& histogram_tester) {
|
||||
// Continue if histogram was already recorded.
|
||||
if (histogram_tester.GetAllSamples(histogram_name).size() > 0) {
|
||||
@ -288,7 +288,7 @@ class SegmentationPlatformTest : public PlatformBrowserTest {
|
||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||
histogram_name,
|
||||
base::BindLambdaForTesting(
|
||||
[&](const char* histogram_name, uint64_t name_hash,
|
||||
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||
run_loop.Run();
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ class SiteProtectionMetricsObserverTest
|
||||
base::StatisticsRecorder::ScopedHistogramSampleObserver observer(
|
||||
histogram_name,
|
||||
base::BindLambdaForTesting(
|
||||
[&](const char* histogram_name, uint64_t name_hash,
|
||||
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||
NavigateAndCommit(url);
|
||||
run_loop.Run();
|
||||
@ -336,7 +336,7 @@ TEST_F(SiteProtectionMetricsObserverTest, IgnoreCurrentNavigationEngagement) {
|
||||
base::StatisticsRecorder::ScopedHistogramSampleObserver observer(
|
||||
"SafeBrowsing.SiteProtection.FamiliarityHeuristic",
|
||||
base::BindLambdaForTesting(
|
||||
[&](const char* histogram_name, uint64_t name_hash,
|
||||
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||
|
||||
NavigateAndCommit(kUrl, ui::PAGE_TRANSITION_TYPED);
|
||||
|
@ -229,7 +229,7 @@ class LensOverlayLiveTest : public signin::test::LiveTest {
|
||||
base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||
histogram_name,
|
||||
base::BindLambdaForTesting(
|
||||
[&](const char* histogram_name, uint64_t name_hash,
|
||||
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||
run_loop.Run();
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ void WaitForHistogram(const std::string& histogram_name) {
|
||||
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||
histogram_name,
|
||||
base::BindLambdaForTesting(
|
||||
[&](const char* histogram_name, uint64_t name_hash,
|
||||
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||
run_loop.Run();
|
||||
}
|
||||
|
@ -47,10 +47,17 @@ std::string GetAppName() {
|
||||
}
|
||||
|
||||
struct HistogramArgs {
|
||||
const char* name;
|
||||
base::DurableStringView durable_name;
|
||||
int minimum;
|
||||
int maximum;
|
||||
size_t bucket_count;
|
||||
|
||||
template <size_t N>
|
||||
HistogramArgs(const char (&literal)[N], int min, int max, size_t count)
|
||||
: durable_name(std::string_view(literal, N - 1)),
|
||||
minimum(min),
|
||||
maximum(max),
|
||||
bucket_count(count) {}
|
||||
};
|
||||
|
||||
// List of metrics to collect using a GroupedHistogram.
|
||||
@ -97,7 +104,7 @@ class GroupedHistogram : public base::Histogram {
|
||||
public:
|
||||
// TODO(crbug.com/40824087): min/max parameters are redundant with "ranges"
|
||||
// and can probably be removed.
|
||||
GroupedHistogram(const char* metric_to_override,
|
||||
GroupedHistogram(base::DurableStringView metric_to_override,
|
||||
Sample32 minimum,
|
||||
Sample32 maximum,
|
||||
const base::BucketRanges* ranges)
|
||||
@ -119,8 +126,7 @@ class GroupedHistogram : public base::Histogram {
|
||||
// Note: This is very inefficient. Fetching the app name (which has a lock)
|
||||
// plus doing a search by name with FactoryGet (which also has a lock) makes
|
||||
// incrementing a metric relatively slow.
|
||||
std::string name(
|
||||
base::StringPrintf("%s.%s", histogram_name(), GetAppName().c_str()));
|
||||
std::string name = base::StrCat({histogram_name(), ".", GetAppName()});
|
||||
HistogramBase* grouped_histogram =
|
||||
base::Histogram::FactoryGet(name,
|
||||
minimum_,
|
||||
@ -143,17 +149,16 @@ class GroupedHistogram : public base::Histogram {
|
||||
// before any Histogram of the same name has been used.
|
||||
// It acts similarly to Histogram::FactoryGet but checks that
|
||||
// the histogram is being newly created and does not already exist.
|
||||
void PreregisterHistogram(const char* name,
|
||||
void PreregisterHistogram(base::DurableStringView durable_name,
|
||||
GroupedHistogram::Sample32 minimum,
|
||||
GroupedHistogram::Sample32 maximum,
|
||||
size_t bucket_count,
|
||||
int32_t flags) {
|
||||
std::string_view name_piece(name);
|
||||
|
||||
DCHECK(base::Histogram::InspectConstructionArguments(
|
||||
name_piece, &minimum, &maximum, &bucket_count));
|
||||
DCHECK(!base::StatisticsRecorder::FindHistogram(name_piece))
|
||||
<< "Failed to preregister " << name << ", Histogram already exists.";
|
||||
*durable_name, &minimum, &maximum, &bucket_count));
|
||||
DCHECK(!base::StatisticsRecorder::FindHistogram(*durable_name))
|
||||
<< "Failed to preregister " << *durable_name
|
||||
<< ", Histogram already exists.";
|
||||
|
||||
// To avoid racy destruction at shutdown, the following will be leaked.
|
||||
base::BucketRanges* ranges = new base::BucketRanges(bucket_count + 1);
|
||||
@ -162,7 +167,7 @@ void PreregisterHistogram(const char* name,
|
||||
base::StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
|
||||
|
||||
GroupedHistogram* tentative_histogram =
|
||||
new GroupedHistogram(name, minimum, maximum, registered_ranges);
|
||||
new GroupedHistogram(durable_name, minimum, maximum, registered_ranges);
|
||||
|
||||
tentative_histogram->SetFlags(flags);
|
||||
base::HistogramBase* histogram =
|
||||
@ -178,10 +183,8 @@ void PreregisterHistogram(const char* name,
|
||||
void PreregisterAllGroupedHistograms() {
|
||||
for (size_t i = 0; i < std::size(kHistogramsToGroup); ++i) {
|
||||
PreregisterHistogram(
|
||||
kHistogramsToGroup[i].name,
|
||||
kHistogramsToGroup[i].minimum,
|
||||
kHistogramsToGroup[i].maximum,
|
||||
kHistogramsToGroup[i].bucket_count,
|
||||
kHistogramsToGroup[i].durable_name, kHistogramsToGroup[i].minimum,
|
||||
kHistogramsToGroup[i].maximum, kHistogramsToGroup[i].bucket_count,
|
||||
base::HistogramBase::kUmaTargetedHistogramFlag);
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ TEST_P(BucketedHistogramTraitsTest, ValidHistogram) {
|
||||
EXPECT_TRUE(mojo::test::SerializeAndDeserialize<mojom::BucketedHistogram>(
|
||||
histogram, output));
|
||||
|
||||
EXPECT_STREQ(output->histogram_name(), "Untrusted.Metric");
|
||||
EXPECT_EQ(output->histogram_name(), "Untrusted.Metric");
|
||||
EXPECT_EQ(output->declared_min(), 1);
|
||||
EXPECT_EQ(output->declared_max(), 10);
|
||||
EXPECT_EQ(output->bucket_count(), 3u);
|
||||
|
@ -57,7 +57,7 @@ class LegacyMetricsHistogramFlattener : public base::HistogramFlattener {
|
||||
DVLOG(3) << "RecordDelta " << histogram.histogram_name();
|
||||
|
||||
fuchsia::legacymetrics::Histogram converted;
|
||||
converted.set_name(histogram.histogram_name());
|
||||
converted.set_name(std::string(histogram.histogram_name()));
|
||||
converted.set_sum(snapshot.sum());
|
||||
|
||||
for (std::unique_ptr<base::SampleCountIterator> it = snapshot.Iterator();
|
||||
|
@ -33,6 +33,11 @@ struct HistogramData {
|
||||
const base::HistogramBase::Count32 total_count;
|
||||
const int64_t sum;
|
||||
|
||||
HistogramData(std::string_view name,
|
||||
base::HistogramBase::Count32 count,
|
||||
int64_t sum)
|
||||
: histogram_name(name), total_count(count), sum(sum) {}
|
||||
|
||||
bool operator==(const HistogramData& other) const {
|
||||
return histogram_name == other.histogram_name &&
|
||||
total_count == other.total_count && sum == other.sum;
|
||||
|
@ -79,8 +79,9 @@ class HistogramFlattenerDeltaRecorder : public base::HistogramFlattener {
|
||||
void RecordDelta(const base::HistogramBase& histogram,
|
||||
const base::HistogramSamples& snapshot) override {
|
||||
// Only remember locally created histograms; they have exactly 2 chars.
|
||||
if (strlen(histogram.histogram_name()) == 2)
|
||||
recorded_delta_histogram_names_.push_back(histogram.histogram_name());
|
||||
if (histogram.histogram_name().length() == 2) {
|
||||
recorded_delta_histogram_names_.emplace_back(histogram.histogram_name());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> GetRecordedDeltaHistogramNames() {
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "components/metrics/histogram_encoder.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "base/metrics/histogram.h"
|
||||
#include "base/metrics/histogram_samples.h"
|
||||
@ -15,7 +15,7 @@ using base::SampleCountIterator;
|
||||
|
||||
namespace metrics {
|
||||
|
||||
void EncodeHistogramDelta(const std::string& histogram_name,
|
||||
void EncodeHistogramDelta(std::string_view histogram_name,
|
||||
const base::HistogramSamples& snapshot,
|
||||
ChromeUserMetricsExtension* uma_proto) {
|
||||
DCHECK_NE(0, snapshot.TotalCount());
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef COMPONENTS_METRICS_HISTOGRAM_ENCODER_H_
|
||||
#define COMPONENTS_METRICS_HISTOGRAM_ENCODER_H_
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
|
||||
|
||||
@ -20,7 +20,7 @@ namespace metrics {
|
||||
|
||||
// Record any changes (histogram deltas of counts from |snapshot|) into
|
||||
// |uma_proto| for the given histogram (|histogram_name|).
|
||||
void EncodeHistogramDelta(const std::string& histogram_name,
|
||||
void EncodeHistogramDelta(std::string_view histogram_name,
|
||||
const base::HistogramSamples& snapshot,
|
||||
ChromeUserMetricsExtension* uma_proto);
|
||||
|
||||
|
@ -466,7 +466,7 @@ void MetricsLog::RecordCoreSystemProfile(
|
||||
#endif
|
||||
}
|
||||
|
||||
void MetricsLog::RecordHistogramDelta(const std::string& histogram_name,
|
||||
void MetricsLog::RecordHistogramDelta(std::string_view histogram_name,
|
||||
const base::HistogramSamples& snapshot) {
|
||||
DCHECK(!closed_);
|
||||
log_metadata_.AddSampleCount(snapshot.TotalCount());
|
||||
|
@ -165,7 +165,7 @@ class MetricsLog {
|
||||
void RecordUserAction(const std::string& key, base::TimeTicks action_time);
|
||||
|
||||
// Record any changes in a given histogram for transmission.
|
||||
void RecordHistogramDelta(const std::string& histogram_name,
|
||||
void RecordHistogramDelta(std::string_view histogram_name,
|
||||
const base::HistogramSamples& snapshot);
|
||||
|
||||
// TODO(rkaplow): I think this can be a little refactored as it currently
|
||||
|
@ -405,7 +405,7 @@ void LogUploadingHistograms(const std::string& compressed_log_data) {
|
||||
auto get_histogram_name = [&](uint64_t name_hash) -> std::string {
|
||||
for (base::HistogramBase* histogram : histograms) {
|
||||
if (histogram->name_hash() == name_hash) {
|
||||
return histogram->histogram_name();
|
||||
return std::string(histogram->histogram_name());
|
||||
}
|
||||
}
|
||||
return base::StrCat({"unnamed ", base::NumberToString(name_hash)});
|
||||
|
@ -241,7 +241,7 @@ void TrainingDataCollectorImpl::OnGetSegmentsInfoList(
|
||||
}
|
||||
|
||||
void TrainingDataCollectorImpl::OnHistogramSignalUpdated(
|
||||
const std::string& histogram_name,
|
||||
std::string_view histogram_name,
|
||||
base::HistogramBase::Sample32 sample) {
|
||||
// Report training data for all models which output collection is triggered by
|
||||
// |histogram_name|.
|
||||
|
@ -69,7 +69,7 @@ class TrainingDataCollectorImpl : public TrainingDataCollector,
|
||||
SuccessCallback callback) override;
|
||||
|
||||
// HistogramSignalHandler::Observer implementation.
|
||||
void OnHistogramSignalUpdated(const std::string& histogram_name,
|
||||
void OnHistogramSignalUpdated(std::string_view histogram_name,
|
||||
base::HistogramBase::Sample32 sample) override;
|
||||
|
||||
// UserActionSignalHandler::Observer implementation.
|
||||
|
@ -63,7 +63,7 @@ void HistogramSignalHandler::EnableMetrics(bool enable_metrics) {
|
||||
|
||||
void HistogramSignalHandler::OnHistogramSample(
|
||||
proto::SignalType signal_type,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) {
|
||||
if (!metrics_enabled_) {
|
||||
@ -91,7 +91,7 @@ void HistogramSignalHandler::RemoveObserver(Observer* observer) {
|
||||
}
|
||||
|
||||
void HistogramSignalHandler::OnSampleWritten(
|
||||
const std::string& histogram_name,
|
||||
std::string_view histogram_name,
|
||||
base::HistogramBase::Sample32 sample,
|
||||
bool success) {
|
||||
if (!success) {
|
||||
|
@ -35,7 +35,7 @@ class HistogramSignalHandler {
|
||||
public:
|
||||
// Called when a histogram signal tracked by segmentation platform is
|
||||
// updated and written to database.
|
||||
virtual void OnHistogramSignalUpdated(const std::string& histogram_name,
|
||||
virtual void OnHistogramSignalUpdated(std::string_view histogram_name,
|
||||
base::HistogramBase::Sample32) = 0;
|
||||
~Observer() override = default;
|
||||
|
||||
@ -65,11 +65,11 @@ class HistogramSignalHandler {
|
||||
|
||||
private:
|
||||
void OnHistogramSample(proto::SignalType signal_type,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample);
|
||||
|
||||
void OnSampleWritten(const std::string& histogram_name,
|
||||
void OnSampleWritten(std::string_view histogram_name,
|
||||
base::HistogramBase::Sample32 sample,
|
||||
bool success);
|
||||
|
||||
|
@ -41,7 +41,7 @@ class MockObserver : public HistogramSignalHandler::Observer {
|
||||
~MockObserver() override = default;
|
||||
MOCK_METHOD(void,
|
||||
OnHistogramSignalUpdated,
|
||||
(const std::string&, base::HistogramBase::Sample32),
|
||||
(std::string_view, base::HistogramBase::Sample32),
|
||||
(override));
|
||||
};
|
||||
|
||||
|
@ -69,7 +69,7 @@ class LazyLevelDb {
|
||||
// to delete the database. Will only attempt a single recovery.
|
||||
ValueStore::Status EnsureDbIsOpen();
|
||||
|
||||
const char* open_histogram_name() const {
|
||||
std::string_view open_histogram_name() const {
|
||||
return open_histogram_->histogram_name();
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/containers/map_util.h"
|
||||
#include "base/immediate_crash.h"
|
||||
#include "base/metrics/histogram_base.h"
|
||||
#include "base/metrics/histogram_samples.h"
|
||||
@ -677,7 +678,7 @@ std::unique_ptr<Browser::Histogram> BrowserHandler::GetHistogramData(
|
||||
}
|
||||
|
||||
auto result = Browser::Histogram::Create()
|
||||
.SetName(histogram.histogram_name())
|
||||
.SetName(std::string(histogram.histogram_name()))
|
||||
.SetSum(data->sum())
|
||||
.SetCount(data->TotalCount())
|
||||
.SetBuckets(std::move(out_buckets))
|
||||
@ -689,7 +690,8 @@ std::unique_ptr<Browser::Histogram> BrowserHandler::GetHistogramData(
|
||||
// If we had subtracted previous data, re-add it to get the full snapshot.
|
||||
data->Add(*previous_data);
|
||||
}
|
||||
histograms_snapshots_[histogram.histogram_name()] = std::move(data);
|
||||
base::InsertOrAssign(histograms_snapshots_, histogram.histogram_name(),
|
||||
std::move(data));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -117,7 +117,7 @@ class BrowserHandler : public DevToolsDomainHandler,
|
||||
base::flat_set<raw_ptr<download::DownloadItem, CtnExperimental>>
|
||||
pending_downloads_;
|
||||
// Stores past histogram snapshots for producing histogram deltas.
|
||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>>
|
||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>, std::less<>>
|
||||
histograms_snapshots_;
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "content/browser/metrics/histograms_monitor.h"
|
||||
|
||||
#include "base/containers/map_util.h"
|
||||
#include "base/metrics/histogram_samples.h"
|
||||
#include "base/metrics/statistics_recorder.h"
|
||||
|
||||
@ -17,8 +18,8 @@ void HistogramsMonitor::StartMonitoring() {
|
||||
histograms_snapshot_.clear();
|
||||
// Save a snapshot of all current histograms that will be used as a baseline.
|
||||
for (const auto* histogram : base::StatisticsRecorder::GetHistograms()) {
|
||||
histograms_snapshot_[histogram->histogram_name()] =
|
||||
histogram->SnapshotSamples();
|
||||
base::InsertOrAssign(histograms_snapshot_, histogram->histogram_name(),
|
||||
histogram->SnapshotSamples());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ class CONTENT_EXPORT HistogramsMonitor {
|
||||
base::Value::List GetDiffInternal(
|
||||
const base::StatisticsRecorder::Histograms& histograms);
|
||||
|
||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>>
|
||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>, std::less<>>
|
||||
histograms_snapshot_;
|
||||
};
|
||||
|
||||
|
@ -473,7 +473,7 @@ void SharedStorageBrowserTestBase::WaitForHistogram(
|
||||
std::make_unique<base::StatisticsRecorder::ScopedHistogramSampleObserver>(
|
||||
histogram_name,
|
||||
base::BindLambdaForTesting(
|
||||
[&](const char* histogram_name, uint64_t name_hash,
|
||||
[&](std::string_view histogram_name, uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) { run_loop.Quit(); }));
|
||||
run_loop.Run();
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ class HistogramRule : public BackgroundTracingRule,
|
||||
void OnHistogramChangedCallback(
|
||||
base::Histogram::Sample32 reference_lower_value,
|
||||
base::Histogram::Sample32 reference_upper_value,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::Histogram::Sample32 actual_value) {
|
||||
DCHECK_EQ(histogram_name, histogram_name_);
|
||||
|
@ -138,8 +138,7 @@ void AboutUIHTMLSource::StartDataRequest(
|
||||
// chrome://histograms, this code could likely be moved to //ios/web.
|
||||
for (base::HistogramBase* histogram : base::StatisticsRecorder::Sort(
|
||||
base::StatisticsRecorder::GetHistograms())) {
|
||||
std::string histogram_name = histogram->histogram_name();
|
||||
if (!base::Contains(histogram_name, path)) {
|
||||
if (!base::Contains(histogram->histogram_name(), path)) {
|
||||
continue;
|
||||
}
|
||||
base::Value::Dict histogram_dict = histogram->ToGraphDict();
|
||||
|
@ -104,7 +104,7 @@ class HistogramTester {
|
||||
// Used to determine the histogram changes made during this instance's
|
||||
// lifecycle. This instance takes ownership of the samples, which are deleted
|
||||
// when the instance is destroyed.
|
||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>>
|
||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>, std::less<>>
|
||||
histograms_snapshot_;
|
||||
};
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "base/containers/map_util.h"
|
||||
#import "base/memory/ptr_util.h"
|
||||
#import "base/metrics/histogram_macros.h"
|
||||
#import "base/metrics/histogram_samples.h"
|
||||
@ -32,7 +33,8 @@ HistogramTester::HistogramTester() {
|
||||
// Record any histogram data that exists when the object is created so it can
|
||||
// be subtracted later.
|
||||
for (const auto* const h : base::StatisticsRecorder::GetHistograms()) {
|
||||
histograms_snapshot_[h->histogram_name()] = h->SnapshotSamples();
|
||||
base::InsertOrAssign(histograms_snapshot_, h->histogram_name(),
|
||||
h->SnapshotSamples());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ void BackgroundTracingAgentImpl::OnHistogramChanged(
|
||||
const std::string& rule_id,
|
||||
base::Histogram::Sample32 histogram_lower_value,
|
||||
base::Histogram::Sample32 histogram_upper_value,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::Histogram::Sample32 actual_value) {
|
||||
if (actual_value < histogram_lower_value ||
|
||||
|
@ -49,7 +49,7 @@ class COMPONENT_EXPORT(BACKGROUND_TRACING_CPP) BackgroundTracingAgentImpl
|
||||
void OnHistogramChanged(const std::string& rule_id,
|
||||
base::Histogram::Sample32 reference_lower_value,
|
||||
base::Histogram::Sample32 reference_upper_value,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::Histogram::Sample32 actual_value);
|
||||
|
||||
@ -61,7 +61,7 @@ class COMPONENT_EXPORT(BACKGROUND_TRACING_CPP) BackgroundTracingAgentImpl
|
||||
base::Time histogram_last_changed_;
|
||||
// Tracks histogram names and corresponding registered callbacks.
|
||||
std::map<
|
||||
std::string,
|
||||
std::string /*=rule_id*/,
|
||||
std::unique_ptr<base::StatisticsRecorder::ScopedHistogramSampleObserver>>
|
||||
histogram_callback_map_;
|
||||
|
||||
|
@ -177,8 +177,8 @@ void CustomEventRecorder::LogHistogram(base::HistogramBase* histogram) {
|
||||
}
|
||||
base::Pickle pickle;
|
||||
samples->Serialize(&pickle);
|
||||
std::string buckets =
|
||||
base::Base64Encode(std::string(pickle.data_as_char(), pickle.size()));
|
||||
std::string buckets = base::Base64Encode(
|
||||
std::string_view(pickle.data_as_char(), pickle.size()));
|
||||
TRACE_EVENT_INSTANT2("benchmark,uma", "UMAHistogramSamples",
|
||||
TRACE_EVENT_SCOPE_PROCESS, "name",
|
||||
histogram->histogram_name(), "buckets", buckets);
|
||||
|
@ -67,7 +67,7 @@ class COMPONENT_EXPORT(TRACING_CPP) CustomEventRecorder
|
||||
// For each of the Histogram that we are tracking, cache the snapshot of their
|
||||
// HistogramSamples from before tracing began. So that we can calculate the
|
||||
// delta when we go to LogHistograms.
|
||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>>
|
||||
std::map<std::string, std::unique_ptr<base::HistogramSamples>, std::less<>>
|
||||
startup_histogram_samples_;
|
||||
std::vector<std::string> histograms_;
|
||||
base::ActionCallback user_action_callback_ =
|
||||
|
@ -37,13 +37,13 @@ std::optional<base::HistogramBase::Sample32> MaybeReferenceValue(
|
||||
|
||||
struct HistogramSamplesIncrementalState {
|
||||
using InternedHistogramName =
|
||||
perfetto::SmallInternedDataTraits::Index<const char*>;
|
||||
perfetto::SmallInternedDataTraits::Index<std::string_view>;
|
||||
|
||||
bool was_cleared = true;
|
||||
InternedHistogramName histogram_names_;
|
||||
|
||||
size_t GetInternedHistogramName(
|
||||
const char* value,
|
||||
std::string_view value,
|
||||
HistogramSamplesDataSource::TraceContext::TracePacketHandle& packet) {
|
||||
size_t iid;
|
||||
if (histogram_names_.LookUpOrInsert(&iid, value)) {
|
||||
@ -52,7 +52,7 @@ struct HistogramSamplesIncrementalState {
|
||||
auto* interned_data = packet->set_interned_data();
|
||||
auto* msg = interned_data->add_histogram_names();
|
||||
msg->set_iid(iid);
|
||||
msg->set_name(value);
|
||||
msg->set_name(value.data(), value.size());
|
||||
return iid;
|
||||
}
|
||||
};
|
||||
@ -136,7 +136,7 @@ void HistogramSamplesDataSource::OnStop(const StopArgs&) {
|
||||
void HistogramSamplesDataSource::OnMetricSample(
|
||||
std::optional<base::HistogramBase::Sample32> reference_lower_value,
|
||||
std::optional<base::HistogramBase::Sample32> reference_upper_value,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) {
|
||||
if ((reference_lower_value && sample < reference_lower_value) ||
|
||||
@ -148,14 +148,14 @@ void HistogramSamplesDataSource::OnMetricSample(
|
||||
}
|
||||
|
||||
void HistogramSamplesDataSource::OnAnyMetricSample(
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample) {
|
||||
OnMetricSampleImpl(histogram_name, name_hash, sample, std::nullopt);
|
||||
}
|
||||
|
||||
void HistogramSamplesDataSource::OnMetricSampleImpl(
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample,
|
||||
std::optional<uintptr_t> instance) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#ifndef SERVICES_TRACING_PUBLIC_CPP_PERFETTO_HISTOGRAM_SAMPLES_DATA_SOURCE_H_
|
||||
#define SERVICES_TRACING_PUBLIC_CPP_PERFETTO_HISTOGRAM_SAMPLES_DATA_SOURCE_H_
|
||||
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "base/component_export.h"
|
||||
@ -45,15 +46,15 @@ class COMPONENT_EXPORT(TRACING_CPP) HistogramSamplesDataSource
|
||||
void OnMetricSample(
|
||||
std::optional<base::HistogramBase::Sample32> reference_lower_value,
|
||||
std::optional<base::HistogramBase::Sample32> reference_upper_value,
|
||||
const char* histogram_name,
|
||||
std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 actual_value);
|
||||
static void OnAnyMetricSample(const char* histogram_name,
|
||||
static void OnAnyMetricSample(std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample);
|
||||
// `instance` identifies the instance that registered a callback, or nullopt
|
||||
// if this is a global callback.
|
||||
static void OnMetricSampleImpl(const char* histogram_name,
|
||||
static void OnMetricSampleImpl(std::string_view histogram_name,
|
||||
uint64_t name_hash,
|
||||
base::HistogramBase::Sample32 sample,
|
||||
std::optional<uintptr_t> instance);
|
||||
|
2
third_party/webrtc_overrides/metrics.cc
vendored
2
third_party/webrtc_overrides/metrics.cc
vendored
@ -47,7 +47,7 @@ Histogram* SparseHistogramFactoryGetEnumeration(std::string_view name,
|
||||
std::string(name), base::HistogramBase::kUmaTargetedHistogramFlag));
|
||||
}
|
||||
|
||||
const char* GetHistogramName(Histogram* histogram_pointer) {
|
||||
std::string_view GetHistogramName(Histogram* histogram_pointer) {
|
||||
base::HistogramBase* ptr =
|
||||
reinterpret_cast<base::HistogramBase*>(histogram_pointer);
|
||||
return ptr->histogram_name();
|
||||
|
Reference in New Issue
Block a user