Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Unified Diff: base/metrics/histogram_macros_internal.h

Issue 2776853002: Make UMA_HISTOGRAM_ENUMERATION work with scoped enums. (Closed)
Patch Set: rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/metrics/histogram_macros.h ('k') | base/metrics/histogram_macros_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/metrics/histogram_macros_internal.h
diff --git a/base/metrics/histogram_macros_internal.h b/base/metrics/histogram_macros_internal.h
index 53e4f11b75d6dcce1fa9ea38817cf481eb8e5a2f..c107a4729d26243d6e81d510e03fb769abb137aa 100644
--- a/base/metrics/histogram_macros_internal.h
+++ b/base/metrics/histogram_macros_internal.h
@@ -5,6 +5,11 @@
#ifndef BASE_METRICS_HISTOGRAM_MACROS_INTERNAL_H_
#define BASE_METRICS_HISTOGRAM_MACROS_INTERNAL_H_
+#include <stdint.h>
+
+#include <limits>
+#include <type_traits>
+
#include "base/atomicops.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
@@ -96,17 +101,42 @@
base::Histogram::FactoryGet(name, min, max, bucket_count, flag))
// This is a helper macro used by other macros and shouldn't be used directly.
-// For an enumeration with N items, recording values in the range [0, N - 1],
-// this macro creates a linear histogram with N + 1 buckets:
-// [0, 1), [1, 2), ..., [N - 1, N), and an overflow bucket [N, infinity).
+// The bucketing scheme is linear with a bucket size of 1. For N items,
+// recording values in the range [0, N - 1] creates a linear histogram with N +
+// 1 buckets:
+// [0, 1), [1, 2), ..., [N - 1, N)
+// and an overflow bucket [N, infinity).
+//
// Code should never emit to the overflow bucket; only to the other N buckets.
-// This allows future versions of Chrome to safely append new entries to the
-// enumeration. Otherwise, the histogram would have [N - 1, infinity) as its
-// overflow bucket, and so the maximal value (N - 1) would be emitted to this
-// overflow bucket. But, if an additional enumerated value were later added, the
-// bucket label for the value (N - 1) would change to [N - 1, N), which would
-// result in different versions of Chrome using different bucket labels for
-// identical data.
+// This allows future versions of Chrome to safely increase the boundary size.
+// Otherwise, the histogram would have [N - 1, infinity) as its overflow bucket,
+// and so the maximal value (N - 1) would be emitted to this overflow bucket.
+// But, if an additional value were later added, the bucket label for
+// the value (N - 1) would change to [N - 1, N), which would result in different
+// versions of Chrome using different bucket labels for identical data.
+#define INTERNAL_HISTOGRAM_EXACT_LINEAR_WITH_FLAG(name, sample, boundary, \
+ flag) \
+ do { \
+ static_assert(!std::is_enum<decltype(sample)>::value, \
+ "|sample| should not be an enum type!"); \
+ static_assert(!std::is_enum<decltype(boundary)>::value, \
+ "|boundary| should not be an enum type!"); \
+ STATIC_HISTOGRAM_POINTER_BLOCK( \
+ name, Add(sample), \
+ base::LinearHistogram::FactoryGet(name, 1, boundary, boundary + 1, \
+ flag)); \
+ } while (0)
+
+// Similar to the previous macro but intended for enumerations. This delegates
+// the work to the previous macro, but supports scoped enumerations as well by
+// forcing an explicit cast to the HistogramBase::Sample integral type.
+//
+// Note the range checks verify two separate issues:
+// - that the declared enum max isn't out of range of HistogramBase::Sample
+// - that the declared enum max is > 0
+//
+// TODO(dcheng): This should assert that the passed in types are actually enum
+// types.
Ilya Sherman 2017/03/31 00:28:14 It looks to me like the current code allows, say,
dcheng 2017/03/31 00:46:00 I'll be addressing this TODO shortly. I expect to
Ilya Sherman 2017/03/31 00:47:15 Okay, lovely -- thanks!
#define INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, boundary, flag) \
do { \
static_assert( \
@@ -115,9 +145,14 @@
std::is_same<std::remove_const<decltype(sample)>::type, \
std::remove_const<decltype(boundary)>::type>::value, \
"|sample| and |boundary| shouldn't be of different enums"); \
- STATIC_HISTOGRAM_POINTER_BLOCK( \
- name, Add(sample), base::LinearHistogram::FactoryGet( \
- name, 1, boundary, boundary + 1, flag)); \
+ static_assert( \
+ static_cast<uintmax_t>(boundary) < \
+ static_cast<uintmax_t>( \
+ std::numeric_limits<base::HistogramBase::Sample>::max()), \
+ "|boundary| is out of range of HistogramBase::Sample"); \
+ INTERNAL_HISTOGRAM_EXACT_LINEAR_WITH_FLAG( \
+ name, static_cast<base::HistogramBase::Sample>(sample), \
+ static_cast<base::HistogramBase::Sample>(boundary), flag); \
} while (0)
// This is a helper macro used by other macros and shouldn't be used directly.
« no previous file with comments | « base/metrics/histogram_macros.h ('k') | base/metrics/histogram_macros_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698