Cleanup histogram classes mixing SetFlags into FactoryGet arguments

Generic cleanup of histogram class, renaming *FactoryGet to FactoryGet,
along with reformatting.

The macros were cleaned up to use common sub-macros rather than
repeating code as much.

Removed ThreadSafeHistogram (and associated ASSET_HISTOGRAM macros)
since this class was not getting used.

I introduced UMA_HISTOGRAM_ENUMERATION to support the common use
of LinearHistograms to count various enumerated values.

I added a Flags argument to all the FactoryGet routines to help avoid 
needing to call SetFlags each time a new sample is Add()ed.  This also
simplifies the code.

This will all help prepare for a "don't histogram at all" macro setting
so that I can test the impact of the histogram macro calls on
performance (since there are now so many active histograms).

BUG=31206
r=raman.tenneti
Review URL: http://codereview.chromium.org/515033

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35295 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: 2753b39e0c2e83d3b497ebadc2d720f12b74db40
diff --git a/base/histogram.cc b/base/histogram.cc
index d55c84f..b7f6cb2 100644
--- a/base/histogram.cc
+++ b/base/histogram.cc
@@ -20,12 +20,8 @@
 
 typedef Histogram::Count Count;
 
-// static
-const int Histogram::kHexRangePrintingFlag = 0x8000;
-
-scoped_refptr<Histogram> Histogram::HistogramFactoryGet(
-    const std::string& name, Sample minimum, Sample maximum,
-    size_t bucket_count) {
+scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name,
+    Sample minimum, Sample maximum, size_t bucket_count, Flags flags) {
   scoped_refptr<Histogram> histogram(NULL);
 
   // Defensive code.
@@ -48,14 +44,15 @@
 
   DCHECK(HISTOGRAM == histogram->histogram_type());
   DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
+  histogram->SetFlags(flags);
   return histogram;
 }
 
-scoped_refptr<Histogram> Histogram::HistogramFactoryGet(
-    const std::string& name, base::TimeDelta minimum, base::TimeDelta maximum,
-    size_t bucket_count) {
-  return HistogramFactoryGet(name,
-      minimum.InMilliseconds(), maximum.InMilliseconds(), bucket_count);
+scoped_refptr<Histogram> Histogram::FactoryGet(const std::string& name,
+    base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count,
+    Flags flags) {
+  return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
+                    bucket_count, flags);
 }
 
 Histogram::Histogram(const std::string& name, Sample minimum,
@@ -64,7 +61,7 @@
     declared_min_(minimum),
     declared_max_(maximum),
     bucket_count_(bucket_count),
-    flags_(0),
+    flags_(kNoFlags),
     ranges_(bucket_count + 1, 0),
     sample_() {
   Initialize();
@@ -76,14 +73,13 @@
     declared_min_(static_cast<int> (minimum.InMilliseconds())),
     declared_max_(static_cast<int> (maximum.InMilliseconds())),
     bucket_count_(bucket_count),
-    flags_(0),
+    flags_(kNoFlags),
     ranges_(bucket_count + 1, 0),
     sample_() {
   Initialize();
 }
 
 Histogram::~Histogram() {
-  DCHECK(!(kPlannedLeakFlag & flags_));
   if (StatisticsRecorder::dump_on_exit()) {
     std::string output;
     WriteAscii(true, "\n", &output);
@@ -184,7 +180,7 @@
 bool Histogram::ValidateBucketRanges() const {
   // Standard assertions that all bucket ranges should satisfy.
   DCHECK(ranges_.size() == bucket_count_ + 1);
-  DCHECK(0 == ranges_[0]);
+  DCHECK_EQ(0, ranges_[0]);
   DCHECK(declared_min() == ranges_[1]);
   DCHECK(declared_max() == ranges_[bucket_count_ - 1]);
   DCHECK(kSampleType_MAX == ranges_[bucket_count_]);
@@ -197,12 +193,12 @@
     declared_min_ = 1;
   if (declared_max_ >= kSampleType_MAX)
     declared_max_ = kSampleType_MAX - 1;
-  DCHECK(declared_min_ > 0);  // We provide underflow bucket.
+  DCHECK_GT(declared_min_, 0);  // We provide underflow bucket.
   DCHECK(declared_min_ <= declared_max_);
-  DCHECK(1 < bucket_count_);
+  DCHECK_LT(1u, bucket_count_);
   size_t maximal_bucket_count = declared_max_ - declared_min_ + 2;
   DCHECK(bucket_count_ <= maximal_bucket_count);
-  DCHECK(0 == ranges_[0]);
+  DCHECK_EQ(0, ranges_[0]);
   ranges_[bucket_count_] = kSampleType_MAX;
   InitializeBucketRange();
   DCHECK(ValidateBucketRanges());
@@ -330,7 +326,7 @@
                 histogram_name().c_str(),
                 sample_count);
   if (0 == sample_count) {
-    DCHECK(0 == snapshot.sum());
+    DCHECK_EQ(0, snapshot.sum());
   } else {
     double average = static_cast<float>(snapshot.sum()) / sample_count;
     double variance = static_cast<float>(snapshot.square_sum())/sample_count
@@ -416,7 +412,7 @@
   int declared_min;
   int declared_max;
   int histogram_type;
-  int flags;
+  int pickle_flags;
   std::string histogram_name;
   SampleSet sample;
 
@@ -425,29 +421,25 @@
       !pickle.ReadInt(&iter, &declared_max) ||
       !pickle.ReadSize(&iter, &bucket_count) ||
       !pickle.ReadInt(&iter, &histogram_type) ||
-      !pickle.ReadInt(&iter, &flags) ||
+      !pickle.ReadInt(&iter, &pickle_flags) ||
       !sample.Histogram::SampleSet::Deserialize(&iter, pickle)) {
     LOG(ERROR) << "Picke error decoding Histogram: " << histogram_name;
     return false;
   }
+  Flags flags = static_cast<Flags>(pickle_flags & ~kIPCSerializationSourceFlag);
 
   DCHECK(histogram_type != NOT_VALID_IN_RENDERER);
 
   scoped_refptr<Histogram> render_histogram(NULL);
 
   if (histogram_type ==  HISTOGRAM) {
-    render_histogram = Histogram::HistogramFactoryGet(
-        histogram_name, declared_min, declared_max, bucket_count);
+    render_histogram = Histogram::FactoryGet(
+        histogram_name, declared_min, declared_max, bucket_count, flags);
   } else if (histogram_type == LINEAR_HISTOGRAM) {
-    render_histogram = LinearHistogram::LinearHistogramFactoryGet(
-        histogram_name, declared_min, declared_max, bucket_count);
+    render_histogram = LinearHistogram::FactoryGet(
+        histogram_name, declared_min, declared_max, bucket_count, flags);
   } else if (histogram_type == BOOLEAN_HISTOGRAM) {
-    render_histogram = BooleanHistogram::BooleanHistogramFactoryGet(
-        histogram_name);
-  } else if (histogram_type == THREAD_SAFE_HISTOGRAM) {
-    render_histogram =
-        ThreadSafeHistogram::ThreadSafeHistogramFactoryGet(
-            histogram_name, declared_min, declared_max, bucket_count);
+    render_histogram = BooleanHistogram::FactoryGet(histogram_name, flags);
   } else {
     LOG(ERROR) << "Error Deserializing Histogram Unknown histogram_type: " <<
         histogram_type;
@@ -463,9 +455,8 @@
     DLOG(INFO) << "Single process mode, histogram observed and not copied: " <<
         histogram_name;
   } else {
+    DCHECK(flags == (flags & render_histogram->flags()));
     render_histogram->AddSampleSet(sample);
-    render_histogram->SetFlags(flags & ~kIPCSerializationSourceFlag
-                               & ~kPlannedLeakFlag);
   }
 
   return true;
@@ -496,9 +487,9 @@
   counts_[index] += count;
   sum_ += count * value;
   square_sum_ += (count * value) * static_cast<int64>(value);
-  DCHECK(counts_[index] >= 0);
-  DCHECK(sum_ >= 0);
-  DCHECK(square_sum_ >= 0);
+  DCHECK_GE(counts_[index], 0);
+  DCHECK_GE(sum_, 0);
+  DCHECK_GE(square_sum_, 0);
 }
 
 Count Histogram::SampleSet::TotalCount() const {
@@ -528,7 +519,7 @@
   square_sum_ -= other.square_sum_;
   for (size_t index = 0; index < counts_.size(); ++index) {
     counts_[index] -= other.counts_[index];
-    DCHECK(counts_[index] >= 0);
+    DCHECK_GE(counts_[index], 0);
   }
 }
 
@@ -545,9 +536,9 @@
 }
 
 bool Histogram::SampleSet::Deserialize(void** iter, const Pickle& pickle) {
-  DCHECK(counts_.size() == 0);
-  DCHECK(sum_ == 0);
-  DCHECK(square_sum_ == 0);
+  DCHECK_EQ(counts_.size(), 0u);
+  DCHECK_EQ(sum_, 0);
+  DCHECK_EQ(square_sum_, 0);
 
   size_t counts_size;
 
@@ -575,9 +566,9 @@
 // buckets.
 //------------------------------------------------------------------------------
 
-scoped_refptr<Histogram> LinearHistogram::LinearHistogramFactoryGet(
+scoped_refptr<Histogram> LinearHistogram::FactoryGet(
     const std::string& name, Sample minimum, Sample maximum,
-    size_t bucket_count) {
+    size_t bucket_count, Flags flags) {
   scoped_refptr<Histogram> histogram(NULL);
 
   if (minimum <= 0)
@@ -598,15 +589,15 @@
 
   DCHECK(LINEAR_HISTOGRAM == histogram->histogram_type());
   DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
-
+  histogram->SetFlags(flags);
   return histogram;
 }
 
-scoped_refptr<Histogram> LinearHistogram::LinearHistogramFactoryGet(
-    const std::string& name, base::TimeDelta minimum, base::TimeDelta maximum,
-    size_t bucket_count) {
-  return LinearHistogramFactoryGet(name, minimum.InMilliseconds(),
-      maximum.InMilliseconds(), bucket_count);
+scoped_refptr<Histogram> LinearHistogram::FactoryGet(const std::string& name,
+    base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count,
+    Flags flags) {
+  return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
+                    bucket_count, flags);
 }
 
 LinearHistogram::LinearHistogram(const std::string& name, Sample minimum,
@@ -647,7 +638,7 @@
 
 
 void LinearHistogram::InitializeBucketRange() {
-  DCHECK(0 < declared_min());  // 0 is the underflow bucket here.
+  DCHECK_LT(0, declared_min());  // 0 is the underflow bucket here.
   double min = declared_min();
   double max = declared_max();
   size_t i;
@@ -670,8 +661,8 @@
 // This section provides implementation for BooleanHistogram.
 //------------------------------------------------------------------------------
 
-scoped_refptr<Histogram> BooleanHistogram::BooleanHistogramFactoryGet(
-    const std::string& name) {
+scoped_refptr<Histogram> BooleanHistogram::FactoryGet(const std::string& name,
+                                                      Flags flags) {
   scoped_refptr<Histogram> histogram(NULL);
 
   if (StatisticsRecorder::FindHistogram(name, &histogram)) {
@@ -686,63 +677,10 @@
   }
 
   DCHECK(BOOLEAN_HISTOGRAM == histogram->histogram_type());
-
+  histogram->SetFlags(flags);
   return histogram;
 }
 
-//------------------------------------------------------------------------------
-// This section provides implementation for ThreadSafeHistogram.
-//------------------------------------------------------------------------------
-
-scoped_refptr<Histogram> ThreadSafeHistogram::ThreadSafeHistogramFactoryGet(
-    const std::string& name, Sample minimum, Sample maximum,
-    size_t bucket_count) {
-  scoped_refptr<Histogram> histogram(NULL);
-
-  if (minimum <= 0)
-    minimum = 1;
-  if (maximum >= kSampleType_MAX)
-    maximum = kSampleType_MAX - 1;
-
-  if (StatisticsRecorder::FindHistogram(name, &histogram)) {
-    DCHECK(histogram.get() != NULL);
-  } else {
-    histogram = new ThreadSafeHistogram(name, minimum, maximum, bucket_count);
-    scoped_refptr<Histogram> registered_histogram(NULL);
-    StatisticsRecorder::FindHistogram(name, &registered_histogram);
-    if (registered_histogram.get() != NULL &&
-        registered_histogram.get() != histogram.get())
-      histogram = registered_histogram;
-  }
-
-  DCHECK(THREAD_SAFE_HISTOGRAM == histogram->histogram_type());
-  DCHECK(histogram->HasConstructorArguments(minimum, maximum, bucket_count));
-  return histogram;
-}
-
-ThreadSafeHistogram::ThreadSafeHistogram(const std::string& name,
-     Sample minimum, Sample maximum, size_t bucket_count)
-    : Histogram(name, minimum, maximum, bucket_count),
-      lock_() {
-  }
-
-void ThreadSafeHistogram::Remove(int value) {
-  if (value >= kSampleType_MAX)
-    value = kSampleType_MAX - 1;
-  size_t index = BucketIndex(value);
-  Accumulate(value, -1, index);
-}
-
-void ThreadSafeHistogram::Accumulate(Sample value, Count count, size_t index) {
-  AutoLock lock(lock_);
-  Histogram::Accumulate(value, count, index);
-}
-
-void ThreadSafeHistogram::SnapshotSample(SampleSet* sample) const {
-  AutoLock lock(lock_);
-  Histogram::SnapshotSample(sample);
-};
-
 
 //------------------------------------------------------------------------------
 // The next section handles global (central) support for all histograms, as well
@@ -862,8 +800,8 @@
        histograms_->end() != it;
        ++it) {
     scoped_refptr<Histogram> histogram = it->second;
-    if (!(histogram->flags() & kIPCSerializationSourceFlag))
-      histogram->SetFlags(kIPCSerializationSourceFlag);
+    if (!(histogram->flags() & Histogram::kIPCSerializationSourceFlag))
+      histogram->SetFlags(Histogram::kIPCSerializationSourceFlag);
     output->push_back(histogram);
   }
 }
diff --git a/base/histogram.h b/base/histogram.h
index 0c94fc0..79de748 100644
--- a/base/histogram.h
+++ b/base/histogram.h
@@ -44,92 +44,59 @@
 // Provide easy general purpose histogram in a macro, just like stats counters.
 // The first four macros use 50 buckets.
 
-#define HISTOGRAM_TIMES(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), base::TimeDelta::FromMilliseconds(1), \
-        base::TimeDelta::FromSeconds(10), 50); \
-    counter->AddTime(sample); \
-  } while (0)
+#define HISTOGRAM_TIMES(name, sample) HISTOGRAM_CUSTOM_TIMES( \
+    name, sample, base::TimeDelta::FromMilliseconds(1), \
+    base::TimeDelta::FromSeconds(10), 50)
 
-#define HISTOGRAM_COUNTS(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), 1, 1000000, 50); \
-    counter->Add(sample); \
-  } while (0)
+#define HISTOGRAM_COUNTS(name, sample) HISTOGRAM_CUSTOM_COUNTS( \
+    name, sample, 1, 1000000, 50)
 
-#define HISTOGRAM_COUNTS_100(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), 1, 100, 50); \
-    counter->Add(sample); \
-  } while (0)
+#define HISTOGRAM_COUNTS_100(name, sample) HISTOGRAM_CUSTOM_COUNTS( \
+    name, sample, 1, 100, 50)
 
-#define HISTOGRAM_COUNTS_10000(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), 1, 10000, 50); \
-    counter->Add(sample); \
-  } while (0)
+#define HISTOGRAM_COUNTS_10000(name, sample) HISTOGRAM_CUSTOM_COUNTS( \
+    name, sample, 1, 10000, 50)
 
 #define HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), min, max, bucket_count); \
+    static scoped_refptr<Histogram> counter = Histogram::FactoryGet( \
+        name, min, max, bucket_count, Histogram::kNoFlags); \
     counter->Add(sample); \
   } while (0)
 
-#define HISTOGRAM_PERCENTAGE(name, under_one_hundred) do { \
-    static scoped_refptr<Histogram> counter = \
-        LinearHistogram::LinearHistogramFactoryGet(\
-            (name), 1, 100, 101); \
-    counter->Add(under_one_hundred); \
-  } while (0)
+#define HISTOGRAM_PERCENTAGE(name, under_one_hundred) \
+    HISTOGRAM_ENUMERATION(name, under_one_hundred, 101)
 
 // For folks that need real specific times, use this to select a precise range
 // of times you want plotted, and the number of buckets you want used.
 #define HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), min, max, bucket_count); \
+    static scoped_refptr<Histogram> counter = Histogram::FactoryGet( \
+        name, min, max, bucket_count, Histogram::kNoFlags); \
     counter->AddTime(sample); \
   } while (0)
 
 // DO NOT USE THIS.  It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES.
 #define HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), min, max, bucket_count); \
+    static scoped_refptr<Histogram> counter = Histogram::FactoryGet( \
+        name, min, max, bucket_count, Histogram::kNoFlags); \
     if ((sample) < (max)) counter->AddTime(sample); \
   } while (0)
 
-//------------------------------------------------------------------------------
-// This macro set is for a histogram that can support both addition and removal
-// of samples. It should be used to render the accumulated asset allocation
-// of some samples.  For example, it can sample memory allocation sizes, and
-// memory releases (as negative samples).
-// To simplify the interface, only non-zero values can be sampled, with positive
-// numbers indicating addition, and negative numbers implying dimunition
-// (removal).
-// Note that the underlying ThreadSafeHistogram() uses locking to ensure that
-// counts are precise (no chance of losing an addition or removal event, due to
-// multithread racing). This precision is required to prevent missed-counts from
-// resulting in drift, as the calls to Remove() for a given value should always
-// be equal in number or fewer than the corresponding calls to Add().
+// Support histograming of an enumerated value.  The samples should always be
+// less than boundary_value.
 
-#define ASSET_HISTOGRAM_COUNTS(name, sample) do { \
-    static scoped_refptr<Histogram> counter = \
-        ThreadSafeHistogram::ThreadSafeHistogramFactoryGet(\
-            (name), 1, 1000000, 50); \
-    if (0 == sample) break; \
-    if (sample >= 0) \
-      counter->Add(sample); \
-    else\
-      counter->Remove(-sample); \
+#define HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \
+    static scoped_refptr<Histogram> counter = LinearHistogram::FactoryGet( \
+        name, 1, boundary_value, boundary_value + 1, Histogram::kNoFlags); \
+    counter->Add(sample); \
   } while (0)
 
+
 //------------------------------------------------------------------------------
 // Define Debug vs non-debug flavors of macros.
 #ifndef NDEBUG
 
 #define DHISTOGRAM_TIMES(name, sample) HISTOGRAM_TIMES(name, sample)
 #define DHISTOGRAM_COUNTS(name, sample) HISTOGRAM_COUNTS(name, sample)
-#define DASSET_HISTOGRAM_COUNTS(name, sample) ASSET_HISTOGRAM_COUNTS(name, \
-                                                                     sample)
 #define DHISTOGRAM_PERCENTAGE(name, under_one_hundred) HISTOGRAM_PERCENTAGE(\
     name, under_one_hundred)
 #define DHISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \
@@ -137,21 +104,22 @@
 #define DHISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) \
     HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count)
 #define DHISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \
-  HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count)
+    HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count)
+#define DHISTOGRAM_ENUMERATION(name, sample, boundary_value) \
+    HISTOGRAM_ENUMERATION(name, sample, boundary_value)
 
 #else  // NDEBUG
 
 #define DHISTOGRAM_TIMES(name, sample) do {} while (0)
 #define DHISTOGRAM_COUNTS(name, sample) do {} while (0)
-#define DASSET_HISTOGRAM_COUNTS(name, sample) do {} while (0)
 #define DHISTOGRAM_PERCENTAGE(name, under_one_hundred) do {} while (0)
 #define DHISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \
     do {} while (0)
 #define DHISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) \
     do {} while (0)
 #define DHISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) \
-  do {} while (0)
-
+    do {} while (0)
+#define DHISTOGRAM_ENUMERATION(name, sample, boundary_value) do {} while (0)
 
 #endif  // NDEBUG
 
@@ -161,109 +129,64 @@
 // Not all systems support such UMA, but if they do, the following macros
 // should work with the service.
 
-static const int kUmaTargetedHistogramFlag = 0x1;
+#define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \
+    name, sample, base::TimeDelta::FromMilliseconds(1), \
+    base::TimeDelta::FromSeconds(10), 50)
 
-// This indicates the histogram is pickled to be sent across an IPC Channel.
-// If we observe this flag during unpickle method, then we are running in a
-// single process mode.
-static const int kIPCSerializationSourceFlag = 1 << 4;
-
-// Some histograms aren't currently destroyed.  Until such users properly
-// decref those histograms, we will mark there histograms as planned to leak so
-// that we can catch any user that directly tries to call delete "directly"
-// rather than using the reference counting features that should take care of
-// this.
-// TODO(jar): Make this flag unnecessary!
-static const int kPlannedLeakFlag = 1 << 5;
-
-#define UMA_HISTOGRAM_TIMES(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), base::TimeDelta::FromMilliseconds(1), \
-        base::TimeDelta::FromSeconds(10), 50); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
-    counter->AddTime(sample); \
-  } while (0)
-
-#define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), base::TimeDelta::FromMilliseconds(10), \
-        base::TimeDelta::FromMinutes(3), 50); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
-    counter->AddTime(sample); \
-  } while (0)
+#define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \
+    name, sample, base::TimeDelta::FromMilliseconds(10), \
+    base::TimeDelta::FromMinutes(3), 50)
 
 // Use this macro when times can routinely be much longer than 10 seconds.
-#define UMA_HISTOGRAM_LONG_TIMES(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), base::TimeDelta::FromMilliseconds(1), \
-        base::TimeDelta::FromHours(1), 50); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
-    counter->AddTime(sample); \
-  } while (0)
+#define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \
+    name, sample, base::TimeDelta::FromMilliseconds(1), \
+    base::TimeDelta::FromHours(1), 50)
 
 #define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), min, max, bucket_count); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
+    static scoped_refptr<Histogram> counter = Histogram::FactoryGet( \
+        name, min, max, bucket_count, Histogram::kUmaTargetedHistogramFlag); \
     counter->AddTime(sample); \
   } while (0)
 
+// DO NOT USE THIS.  It is being phased out, in favor of HISTOGRAM_CUSTOM_TIMES.
 #define UMA_HISTOGRAM_CLIPPED_TIMES(name, sample, min, max, bucket_count) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), min, max, bucket_count); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
+    static scoped_refptr<Histogram> counter = Histogram::FactoryGet( \
+        name, min, max, bucket_count, Histogram::kUmaTargetedHistogramFlag); \
     if ((sample) < (max)) counter->AddTime(sample); \
   } while (0)
 
-#define UMA_HISTOGRAM_COUNTS(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), 1, 1000000, 50); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
-    counter->Add(sample); \
-  } while (0)
+#define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
+    name, sample, 1, 1000000, 50)
 
-#define UMA_HISTOGRAM_COUNTS_100(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), 1, 100, 50); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
-    counter->Add(sample); \
-  } while (0)
+#define UMA_HISTOGRAM_COUNTS_100(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
+    name, sample, 1, 100, 50)
 
-#define UMA_HISTOGRAM_COUNTS_10000(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), 1, 10000, 50); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
-    counter->Add(sample); \
-  } while (0)
+#define UMA_HISTOGRAM_COUNTS_10000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
+    name, sample, 1, 10000, 50)
 
 #define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), min, max, bucket_count); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
+    static scoped_refptr<Histogram> counter = Histogram::FactoryGet( \
+        name, min, max, bucket_count, Histogram::kUmaTargetedHistogramFlag); \
     counter->Add(sample); \
   } while (0)
 
-#define UMA_HISTOGRAM_MEMORY_KB(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), 1000, 500000, 50); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
+#define UMA_HISTOGRAM_MEMORY_KB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
+    name, sample, 1000, 500000, 50)
+
+#define UMA_HISTOGRAM_MEMORY_MB(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
+    name, sample, 1, 1000, 50)
+
+#define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) \
+    UMA_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101)
+
+#define UMA_HISTOGRAM_ENUMERATION(name, sample, boundary_value) do { \
+    DCHECK(sample < boundary_value); \
+    static scoped_refptr<Histogram> counter = LinearHistogram::FactoryGet( \
+        name, 1, boundary_value, boundary_value + 1, \
+        Histogram::kUmaTargetedHistogramFlag); \
     counter->Add(sample); \
   } while (0)
 
-#define UMA_HISTOGRAM_MEMORY_MB(name, sample) do { \
-    static scoped_refptr<Histogram> counter = Histogram::HistogramFactoryGet(\
-        (name), 1, 1000, 50); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
-    counter->Add(sample); \
-  } while (0)
-
-#define UMA_HISTOGRAM_PERCENTAGE(name, under_one_hundred) do { \
-    static scoped_refptr<Histogram> counter = \
-        LinearHistogram::LinearHistogramFactoryGet(\
-            (name), 1, 100, 101); \
-    counter->SetFlags(kUmaTargetedHistogramFlag); \
-    counter->Add(under_one_hundred); \
-  } while (0)
 
 //------------------------------------------------------------------------------
 
@@ -271,7 +194,6 @@
 class Histogram;
 class LinearHistogram;
 class BooleanHistogram;
-class ThreadSafeHistogram;
 
 namespace disk_cache {
   class StatsHistogram;
@@ -287,15 +209,12 @@
   typedef std::vector<Count> Counts;
   typedef std::vector<Sample> Ranges;
 
-  static const int kHexRangePrintingFlag;
-
   /* These enums are meant to facilitate deserialization of renderer histograms
      into the browser. */
   enum ClassType {
     HISTOGRAM,
     LINEAR_HISTOGRAM,
     BOOLEAN_HISTOGRAM,
-    THREAD_SAFE_HISTOGRAM,
     NOT_VALID_IN_RENDERER
   };
 
@@ -304,6 +223,20 @@
     LINEAR
   };
 
+  enum Flags {
+    kNoFlags = 0,
+    kUmaTargetedHistogramFlag = 0x1,  // Histogram should be UMA uploaded.
+
+    // Indicate that the histogram was pickled to be sent across an IPC Channel.
+    // If we observe this flag on a histogram being aggregated into after IPC,
+    // then we are running in a single process mode, and the aggregation should
+    // not take place (as we would be aggregating back into the source
+    // histogram!).
+    kIPCSerializationSourceFlag = 0x10,
+
+    kHexRangePrintingFlag = 0x8000,  // Fancy bucket-naming supported.
+  };
+
   struct DescriptionPair {
     Sample sample;
     const char* description;  // Null means end of a list of pairs.
@@ -348,10 +281,11 @@
   //----------------------------------------------------------------------------
   // minimum should start from 1. 0 is invalid as a minimum. 0 is an implicit
   // default underflow bucket.
-  static scoped_refptr<Histogram> HistogramFactoryGet(const std::string& name,
-      Sample minimum, Sample maximum, size_t bucket_count);
-  static scoped_refptr<Histogram> HistogramFactoryGet(const std::string& name,
-      base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count);
+  static scoped_refptr<Histogram> FactoryGet(const std::string& name,
+      Sample minimum, Sample maximum, size_t bucket_count, Flags flags);
+  static scoped_refptr<Histogram> FactoryGet(const std::string& name,
+      base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count,
+      Flags flags);
 
   void Add(int value);
 
@@ -365,9 +299,6 @@
 
   void AddSampleSet(const SampleSet& sample);
 
-  // This method is an interface, used only by ThreadSafeHistogram.
-  virtual void Remove(int value) { DCHECK(false); }
-
   // This method is an interface, used only by LinearHistogram.
   virtual void SetRangeDescriptions(const DescriptionPair descriptions[])
       { DCHECK(false); }
@@ -380,8 +311,8 @@
   // Support generic flagging of Histograms.
   // 0x1 Currently used to mark this histogram to be recorded by UMA..
   // 0x8000 means print ranges in hex.
-  void SetFlags(int flags) { flags_ |= flags; }
-  void ClearFlags(int flags) { flags_ &= ~flags; }
+  void SetFlags(Flags flags) { flags_ = static_cast<Flags> (flags_ | flags); }
+  void ClearFlags(Flags flags) { flags_ = static_cast<Flags>(flags_ & ~flags); }
   int flags() const { return flags_; }
 
   // Convenience methods for serializing/deserializing the histograms.
@@ -510,7 +441,7 @@
   size_t bucket_count_;  // Dimension of counts_[].
 
   // Flag the histogram for recording by UMA via metric_services.h.
-  int flags_;
+  Flags flags_;
 
   // For each index, show the least value that can be stored in the
   // corresponding bucket. We also append one extra element in this array,
@@ -539,12 +470,11 @@
 
   /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit
      default underflow bucket. */
-  static scoped_refptr<Histogram> LinearHistogramFactoryGet(
-      const std::string& name, Sample minimum, Sample maximum,
-      size_t bucket_count);
-  static scoped_refptr<Histogram> LinearHistogramFactoryGet(
-      const std::string& name, base::TimeDelta minimum,
-      base::TimeDelta maximum, size_t bucket_count);
+  static scoped_refptr<Histogram> FactoryGet(const std::string& name,
+      Sample minimum, Sample maximum, size_t bucket_count, Flags flags);
+  static scoped_refptr<Histogram> FactoryGet(const std::string& name,
+      base::TimeDelta minimum, base::TimeDelta maximum, size_t bucket_count,
+      Flags flags);
 
  protected:
   LinearHistogram(const std::string& name, Sample minimum,
@@ -582,8 +512,8 @@
 // BooleanHistogram is a histogram for booleans.
 class BooleanHistogram : public LinearHistogram {
  public:
-  static scoped_refptr<Histogram> BooleanHistogramFactoryGet(
-      const std::string& name);
+  static scoped_refptr<Histogram> FactoryGet(const std::string& name,
+      Flags flags);
 
   virtual ClassType histogram_type() const { return BOOLEAN_HISTOGRAM; }
 
@@ -591,45 +521,13 @@
 
  private:
   explicit BooleanHistogram(const std::string& name)
-    : LinearHistogram(name, 1, 2, 3) {
+      : LinearHistogram(name, 1, 2, 3) {
   }
 
   DISALLOW_COPY_AND_ASSIGN(BooleanHistogram);
 };
 
 //------------------------------------------------------------------------------
-// This section provides implementation for ThreadSafeHistogram.
-//------------------------------------------------------------------------------
-
-class ThreadSafeHistogram : public Histogram {
- public:
-  static scoped_refptr<Histogram> ThreadSafeHistogramFactoryGet(
-      const std::string& name, Sample minimum, Sample maximum,
-      size_t bucket_count);
-
-  virtual ClassType histogram_type() const { return THREAD_SAFE_HISTOGRAM; }
-
-  // Provide the analog to Add()
-  virtual void Remove(int value);
-
- protected:
-  ThreadSafeHistogram(const std::string& name, Sample minimum,
-                      Sample maximum, size_t bucket_count);
-
-  virtual ~ThreadSafeHistogram() {}
-
-  // Provide locked versions to get precise counts.
-  virtual void Accumulate(Sample value, Count count, size_t index);
-
-  virtual void SnapshotSample(SampleSet* sample) const;
-
- private:
-  mutable Lock lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThreadSafeHistogram);
-};
-
-//------------------------------------------------------------------------------
 // StatisticsRecorder handles all histograms in the system.  It provides a
 // general place for histograms to register, and supports a global API for
 // accessing (i.e., dumping, or graphing) the data in all the histograms.
diff --git a/base/histogram_unittest.cc b/base/histogram_unittest.cc
index 4d5de51..f702a2e 100644
--- a/base/histogram_unittest.cc
+++ b/base/histogram_unittest.cc
@@ -19,17 +19,15 @@
 // Check for basic syntax and use.
 TEST(HistogramTest, StartupShutdownTest) {
   // Try basic construction
-  scoped_refptr<Histogram> histogram =
-    Histogram::HistogramFactoryGet("TestHistogram", 1, 1000, 10);
-  scoped_refptr<Histogram> histogram1 =
-      Histogram::HistogramFactoryGet("Test1Histogram", 1, 1000, 10);
+  scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
+      "TestHistogram", 1, 1000, 10, Histogram::kNoFlags);
+  scoped_refptr<Histogram> histogram1 = Histogram::FactoryGet(
+      "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags);
 
-  scoped_refptr<Histogram> linear_histogram =
-      LinearHistogram::LinearHistogramFactoryGet("TestLinearHistogram", 1, 1000,
-          10);
-  scoped_refptr<Histogram> linear_histogram1 =
-      LinearHistogram::LinearHistogramFactoryGet("Test1LinearHistogram", 1,
-          1000, 10);
+  scoped_refptr<Histogram> linear_histogram = LinearHistogram::FactoryGet(
+      "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags);
+  scoped_refptr<Histogram> linear_histogram1 = LinearHistogram::FactoryGet(
+      "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags);
 
   // Use standard macros (but with fixed samples)
   HISTOGRAM_TIMES("Test2Histogram", TimeDelta::FromDays(1));
@@ -38,7 +36,7 @@
   DHISTOGRAM_TIMES("Test4Histogram", TimeDelta::FromDays(1));
   DHISTOGRAM_COUNTS("Test5Histogram", 30);
 
-  ASSET_HISTOGRAM_COUNTS("Test6Histogram", 129);
+  HISTOGRAM_ENUMERATION("Test6Histogram", 129, 130);
 
   // Try to construct samples.
   Histogram::SampleSet sample1;
@@ -63,23 +61,21 @@
   EXPECT_EQ(0U, histograms.size());
 
   // Try basic construction
-  scoped_refptr<Histogram> histogram =
-      Histogram::HistogramFactoryGet("TestHistogram", 1, 1000, 10);
+  scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
+      "TestHistogram", 1, 1000, 10, Histogram::kNoFlags);
   histograms.clear();
   StatisticsRecorder::GetHistograms(&histograms);  // Load up lists
   EXPECT_EQ(1U, histograms.size());
-  scoped_refptr<Histogram> histogram1 =
-      Histogram::HistogramFactoryGet("Test1Histogram", 1, 1000, 10);
+  scoped_refptr<Histogram> histogram1 = Histogram::FactoryGet(
+      "Test1Histogram", 1, 1000, 10, Histogram::kNoFlags);
   histograms.clear();
   StatisticsRecorder::GetHistograms(&histograms);  // Load up lists
   EXPECT_EQ(2U, histograms.size());
 
-  scoped_refptr<Histogram> linear_histogram =
-      LinearHistogram::LinearHistogramFactoryGet(
-          "TestLinearHistogram", 1, 1000, 10);
-  scoped_refptr<Histogram> linear_histogram1 =
-      LinearHistogram::LinearHistogramFactoryGet(
-          "Test1LinearHistogram", 1, 1000, 10);
+  scoped_refptr<Histogram> linear_histogram = LinearHistogram::FactoryGet(
+      "TestLinearHistogram", 1, 1000, 10, Histogram::kNoFlags);
+  scoped_refptr<Histogram> linear_histogram1 = LinearHistogram::FactoryGet(
+      "Test1LinearHistogram", 1, 1000, 10, Histogram::kNoFlags);
   histograms.clear();
   StatisticsRecorder::GetHistograms(&histograms);  // Load up lists
   EXPECT_EQ(4U, histograms.size());
@@ -91,7 +87,7 @@
   StatisticsRecorder::GetHistograms(&histograms);  // Load up lists
   EXPECT_EQ(6U, histograms.size());
 
-  ASSET_HISTOGRAM_COUNTS("TestAssetHistogram", 1000);
+  HISTOGRAM_ENUMERATION("TestEnumerationHistogram", 20, 200);
   histograms.clear();
   StatisticsRecorder::GetHistograms(&histograms);  // Load up lists
   EXPECT_EQ(7U, histograms.size());
@@ -114,8 +110,8 @@
   recorder.GetHistograms(&histograms);
   EXPECT_EQ(0U, histograms.size());
 
-  scoped_refptr<Histogram> histogram = Histogram::HistogramFactoryGet(
-      "Histogram", 1, 64, 8);  // As mentioned in header file.
+  scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
+      "Histogram", 1, 64, 8, Histogram::kNoFlags);  // As per header file.
   // Check that we got a nice exponential when there was enough rooom.
   EXPECT_EQ(0, histogram->ranges(0));
   int power_of_2 = 1;
@@ -125,51 +121,48 @@
   }
   EXPECT_EQ(INT_MAX, histogram->ranges(8));
 
-  scoped_refptr<Histogram> short_histogram =
-      Histogram::HistogramFactoryGet("Histogram Shortened", 1, 7, 8);
+  scoped_refptr<Histogram> short_histogram = Histogram::FactoryGet(
+      "Histogram Shortened", 1, 7, 8, Histogram::kNoFlags);
   // Check that when the number of buckets is short, we get a linear histogram
   // for lack of space to do otherwise.
   for (int i = 0; i < 8; i++)
     EXPECT_EQ(i, short_histogram->ranges(i));
   EXPECT_EQ(INT_MAX, short_histogram->ranges(8));
 
-  scoped_refptr<Histogram> linear_histogram =
-      LinearHistogram::LinearHistogramFactoryGet("Linear", 1, 7, 8);
+  scoped_refptr<Histogram> linear_histogram = LinearHistogram::FactoryGet(
+      "Linear", 1, 7, 8, Histogram::kNoFlags);
   // We also get a nice linear set of bucket ranges when we ask for it
   for (int i = 0; i < 8; i++)
     EXPECT_EQ(i, linear_histogram->ranges(i));
   EXPECT_EQ(INT_MAX, linear_histogram->ranges(8));
 
-  scoped_refptr<Histogram> linear_broad_histogram =
-      LinearHistogram::LinearHistogramFactoryGet(
-          "Linear widened", 2, 14, 8);
+  scoped_refptr<Histogram> linear_broad_histogram = LinearHistogram::FactoryGet(
+      "Linear widened", 2, 14, 8, Histogram::kNoFlags);
   // ...but when the list has more space, then the ranges naturally spread out.
   for (int i = 0; i < 8; i++)
     EXPECT_EQ(2 * i, linear_broad_histogram->ranges(i));
   EXPECT_EQ(INT_MAX, linear_broad_histogram->ranges(8));
 
-  scoped_refptr<Histogram> threadsafe_histogram =
-      ThreadSafeHistogram::ThreadSafeHistogramFactoryGet("ThreadSafe", 1, 32,
-          15);
+  scoped_refptr<Histogram> transitioning_histogram =
+      Histogram::FactoryGet("LinearAndExponential", 1, 32, 15,
+                                      Histogram::kNoFlags);
   // When space is a little tight, we transition from linear to exponential.
-  // This is what happens in both the basic histogram, and the threadsafe
-  // variant (which is derived).
-  EXPECT_EQ(0, threadsafe_histogram->ranges(0));
-  EXPECT_EQ(1, threadsafe_histogram->ranges(1));
-  EXPECT_EQ(2, threadsafe_histogram->ranges(2));
-  EXPECT_EQ(3, threadsafe_histogram->ranges(3));
-  EXPECT_EQ(4, threadsafe_histogram->ranges(4));
-  EXPECT_EQ(5, threadsafe_histogram->ranges(5));
-  EXPECT_EQ(6, threadsafe_histogram->ranges(6));
-  EXPECT_EQ(7, threadsafe_histogram->ranges(7));
-  EXPECT_EQ(9, threadsafe_histogram->ranges(8));
-  EXPECT_EQ(11, threadsafe_histogram->ranges(9));
-  EXPECT_EQ(14, threadsafe_histogram->ranges(10));
-  EXPECT_EQ(17, threadsafe_histogram->ranges(11));
-  EXPECT_EQ(21, threadsafe_histogram->ranges(12));
-  EXPECT_EQ(26, threadsafe_histogram->ranges(13));
-  EXPECT_EQ(32, threadsafe_histogram->ranges(14));
-  EXPECT_EQ(INT_MAX, threadsafe_histogram->ranges(15));
+  EXPECT_EQ(0, transitioning_histogram->ranges(0));
+  EXPECT_EQ(1, transitioning_histogram->ranges(1));
+  EXPECT_EQ(2, transitioning_histogram->ranges(2));
+  EXPECT_EQ(3, transitioning_histogram->ranges(3));
+  EXPECT_EQ(4, transitioning_histogram->ranges(4));
+  EXPECT_EQ(5, transitioning_histogram->ranges(5));
+  EXPECT_EQ(6, transitioning_histogram->ranges(6));
+  EXPECT_EQ(7, transitioning_histogram->ranges(7));
+  EXPECT_EQ(9, transitioning_histogram->ranges(8));
+  EXPECT_EQ(11, transitioning_histogram->ranges(9));
+  EXPECT_EQ(14, transitioning_histogram->ranges(10));
+  EXPECT_EQ(17, transitioning_histogram->ranges(11));
+  EXPECT_EQ(21, transitioning_histogram->ranges(12));
+  EXPECT_EQ(26, transitioning_histogram->ranges(13));
+  EXPECT_EQ(32, transitioning_histogram->ranges(14));
+  EXPECT_EQ(INT_MAX, transitioning_histogram->ranges(15));
 
   recorder.GetHistograms(&histograms);
   EXPECT_EQ(5U, histograms.size());
@@ -178,8 +171,8 @@
 // Make sure histogram handles out-of-bounds data gracefully.
 TEST(HistogramTest, BoundsTest) {
   const size_t kBucketCount = 50;
-  scoped_refptr<Histogram> histogram = Histogram::HistogramFactoryGet("Bounded",
-     10, 100, kBucketCount);
+  scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
+      "Bounded", 10, 100, kBucketCount, Histogram::kNoFlags);
 
   // Put two samples "out of bounds" above and below.
   histogram->Add(5);
@@ -201,8 +194,8 @@
 
 // Check to be sure samples land as expected is "correct" buckets.
 TEST(HistogramTest, BucketPlacementTest) {
-  scoped_refptr<Histogram> histogram = Histogram::HistogramFactoryGet(
-      "Histogram", 1, 64, 8);  // As mentioned in header file.
+  scoped_refptr<Histogram> histogram = Histogram::FactoryGet(
+      "Histogram", 1, 64, 8, Histogram::kNoFlags);  // As per header file.
 
   // Check that we got a nice exponential since there was enough rooom.
   EXPECT_EQ(0, histogram->ranges(0));
@@ -231,84 +224,5 @@
     EXPECT_EQ(i + 1, sample.counts(i));
 }
 
-static const char kAssetTestHistogramName[] = "AssetCountTest";
-static const char kAssetTestDebugHistogramName[] = "DAssetCountTest";
-void AssetCountFunction(int sample) {
-  ASSET_HISTOGRAM_COUNTS(kAssetTestHistogramName, sample);
-  DASSET_HISTOGRAM_COUNTS(kAssetTestDebugHistogramName, sample);
-}
-// Check that asset can be added and removed from buckets.
-TEST(HistogramTest, AssetCountTest) {
-  // Start up a recorder system to identify all histograms.
-  StatisticsRecorder recorder;
-
-  // Call through the macro to instantiate the static variables.
-  AssetCountFunction(100);  // Put a sample in the bucket for 100.
-
-  // Find the histogram.
-  StatisticsRecorder::Histograms histogram_list;
-  StatisticsRecorder::GetHistograms(&histogram_list);
-  ASSERT_NE(0U, histogram_list.size());
-  const Histogram* our_histogram = NULL;
-  const Histogram* our_debug_histogram = NULL;
-  for (StatisticsRecorder::Histograms::iterator it = histogram_list.begin();
-       it != histogram_list.end();
-       ++it) {
-    if (!(*it)->histogram_name().compare(kAssetTestHistogramName))
-      our_histogram = *it;
-    else if (!(*it)->histogram_name().compare(kAssetTestDebugHistogramName)) {
-      our_debug_histogram = *it;
-    }
-  }
-  ASSERT_TRUE(our_histogram);
-#ifndef NDEBUG
-  EXPECT_TRUE(our_debug_histogram);
-#else
-  EXPECT_FALSE(our_debug_histogram);
-#endif
-  // Verify it has a 1 in exactly one bucket (where we put the sample).
-  Histogram::SampleSet sample;
-  our_histogram->SnapshotSample(&sample);
-  int match_count = 0;
-  for (size_t i = 0; i < our_histogram->bucket_count(); ++i) {
-    if (sample.counts(i) > 0) {
-      EXPECT_LT(++match_count, 2) << "extra count in bucket " << i;
-    }
-  }
-  EXPECT_EQ(1, match_count);
-
-  // Remove our sample.
-  AssetCountFunction(-100);  // Remove a sample from the bucket for 100.
-  our_histogram->SnapshotSample(&sample);  // Extract data set.
-
-  // Verify that the bucket is now empty, as are all the other buckets.
-  for (size_t i = 0; i < our_histogram->bucket_count(); ++i) {
-    EXPECT_EQ(0, sample.counts(i)) << "extra count in bucket " << i;
-  }
-
-  if (!our_debug_histogram)
-    return;  // This is a production build.
-
-  // Repeat test with debug histogram.  Note that insertion and deletion above
-  // should have cancelled each other out.
-  AssetCountFunction(100);  // Add a sample into the bucket for 100.
-  our_debug_histogram->SnapshotSample(&sample);
-  match_count = 0;
-  for (size_t i = 0; i < our_debug_histogram->bucket_count(); ++i) {
-    if (sample.counts(i) > 0) {
-      EXPECT_LT(++match_count, 2) << "extra count in bucket " << i;
-    }
-  }
-  EXPECT_EQ(1, match_count);
-
-  // Remove our sample.
-  AssetCountFunction(-100);  // Remove a sample from the bucket for 100.
-  our_debug_histogram->SnapshotSample(&sample);  // Extract data set.
-
-  // Verify that the bucket is now empty, as are all the other buckets.
-  for (size_t i = 0; i < our_debug_histogram->bucket_count(); ++i) {
-    EXPECT_EQ(0, sample.counts(i)) << "extra count in bucket " << i;
-  }
-}
 
 }  // namespace
diff --git a/base/message_loop.cc b/base/message_loop.cc
index 64913e5..9799100 100644
--- a/base/message_loop.cc
+++ b/base/message_loop.cc
@@ -265,7 +265,7 @@
     pending_task.delayed_run_time =
         Time::Now() + TimeDelta::FromMilliseconds(delay_ms);
   } else {
-    DCHECK(delay_ms == 0) << "delay should not be negative";
+    DCHECK_EQ(delay_ms, 0) << "delay should not be negative";
   }
 
   // Warning: Don't try to short-circuit, and handle this thread's tasks more
@@ -531,13 +531,10 @@
   if (enable_histogrammer_ && !message_histogram_.get()
       && StatisticsRecorder::WasStarted()) {
     DCHECK(!thread_name_.empty());
-    message_histogram_ =
-        LinearHistogram::LinearHistogramFactoryGet(
-                            ("MsgLoop:" + thread_name_),
-                            kLeastNonZeroMessageId,
-                            kMaxMessageId,
-                            kNumberOfDistinctMessagesDisplayed);
-    message_histogram_->SetFlags(message_histogram_->kHexRangePrintingFlag);
+    message_histogram_ = LinearHistogram::FactoryGet("MsgLoop:" + thread_name_,
+        kLeastNonZeroMessageId, kMaxMessageId,
+        kNumberOfDistinctMessagesDisplayed,
+        message_histogram_->kHexRangePrintingFlag);
     message_histogram_->SetRangeDescriptions(event_descriptions_);
   }
 }