diff --git a/base/debug/activity_tracker.cc b/base/debug/activity_tracker.cc
deleted file mode 100644
index bb1349c..0000000
--- a/base/debug/activity_tracker.cc
+++ /dev/null
@@ -1,1828 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/debug/activity_tracker.h"
-
-#include <algorithm>
-#include <limits>
-#include <utility>
-
-#include "base/atomic_sequence_num.h"
-#include "base/debug/stack_trace.h"
-#include "base/files/file.h"
-#include "base/files/file_path.h"
-#include "base/files/memory_mapped_file.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/pending_task.h"
-#include "base/pickle.h"
-#include "base/process/process.h"
-#include "base/process/process_handle.h"
-#include "base/stl_util.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/threading/platform_thread.h"
-#include "build_config.h"
-
-namespace base {
-namespace debug {
-
-namespace {
-
-// The minimum depth a stack should support.
-const int kMinStackDepth = 2;
-
-// The amount of memory set aside for holding arbitrary user data (key/value
-// pairs) globally or associated with ActivityData entries.
-const size_t kUserDataSize = 1 << 10;     // 1 KiB
-const size_t kProcessDataSize = 4 << 10;  // 4 KiB
-const size_t kMaxUserDataNameLength =
-    static_cast<size_t>(std::numeric_limits<uint8_t>::max());
-
-// A constant used to indicate that module information is changing.
-const uint32_t kModuleInformationChanging = 0x80000000;
-
-// The key used to record process information.
-const char kProcessPhaseDataKey[] = "process-phase";
-
-// An atomically incrementing number, used to check for recreations of objects
-// in the same memory space.
-AtomicSequenceNumber g_next_id;
-
-union ThreadRef {
-  int64_t as_id;
-#if defined(OS_WIN)
-  // On Windows, the handle itself is often a pseudo-handle with a common
-  // value meaning "this thread" and so the thread-id is used. The former
-  // can be converted to a thread-id with a system call.
-  PlatformThreadId as_tid;
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
-  // On Posix and Fuchsia, the handle is always a unique identifier so no
-  // conversion needs to be done. However, its value is officially opaque so
-  // there is no one correct way to convert it to a numerical identifier.
-  PlatformThreadHandle::Handle as_handle;
-#endif
-};
-
-// Gets the next non-zero identifier. It is only unique within a process.
-uint32_t GetNextDataId() {
-  uint32_t id;
-  while ((id = g_next_id.GetNext()) == 0)
-    ;
-  return id;
-}
-
-// Gets the current process-id, either from the GlobalActivityTracker if it
-// exists (where the PID can be defined for testing) or from the system if
-// there isn't such.
-int64_t GetProcessId() {
-  GlobalActivityTracker* global = GlobalActivityTracker::Get();
-  if (global)
-    return global->process_id();
-  return GetCurrentProcId();
-}
-
-// Finds and reuses a specific allocation or creates a new one.
-PersistentMemoryAllocator::Reference AllocateFrom(
-    PersistentMemoryAllocator* allocator,
-    uint32_t from_type,
-    size_t size,
-    uint32_t to_type) {
-  PersistentMemoryAllocator::Iterator iter(allocator);
-  PersistentMemoryAllocator::Reference ref;
-  while ((ref = iter.GetNextOfType(from_type)) != 0) {
-    DCHECK_LE(size, allocator->GetAllocSize(ref));
-    // This can fail if a another thread has just taken it. It is assumed that
-    // the memory is cleared during the "free" operation.
-    if (allocator->ChangeType(ref, to_type, from_type, /*clear=*/false))
-      return ref;
-  }
-
-  return allocator->Allocate(size, to_type);
-}
-
-// Determines the previous aligned index.
-size_t RoundDownToAlignment(size_t index, size_t alignment) {
-  return index & (0 - alignment);
-}
-
-// Determines the next aligned index.
-size_t RoundUpToAlignment(size_t index, size_t alignment) {
-  return (index + (alignment - 1)) & (0 - alignment);
-}
-
-// Converts "tick" timing into wall time.
-Time WallTimeFromTickTime(int64_t ticks_start, int64_t ticks, Time time_start) {
-  return time_start + TimeDelta::FromInternalValue(ticks - ticks_start);
-}
-
-}  // namespace
-
-OwningProcess::OwningProcess() = default;
-OwningProcess::~OwningProcess() = default;
-
-void OwningProcess::Release_Initialize(int64_t pid) {
-  uint32_t old_id = data_id.load(std::memory_order_acquire);
-  DCHECK_EQ(0U, old_id);
-  process_id = pid != 0 ? pid : GetProcessId();
-  create_stamp = Time::Now().ToInternalValue();
-  data_id.store(GetNextDataId(), std::memory_order_release);
-}
-
-void OwningProcess::SetOwningProcessIdForTesting(int64_t pid, int64_t stamp) {
-  DCHECK_NE(0U, data_id);
-  process_id = pid;
-  create_stamp = stamp;
-}
-
-// static
-bool OwningProcess::GetOwningProcessId(const void* memory,
-                                       int64_t* out_id,
-                                       int64_t* out_stamp) {
-  const OwningProcess* info = reinterpret_cast<const OwningProcess*>(memory);
-  uint32_t id = info->data_id.load(std::memory_order_acquire);
-  if (id == 0)
-    return false;
-
-  *out_id = info->process_id;
-  *out_stamp = info->create_stamp;
-  return id == info->data_id.load(std::memory_order_seq_cst);
-}
-
-// It doesn't matter what is contained in this (though it will be all zeros)
-// as only the address of it is important.
-const ActivityData kNullActivityData = {};
-
-ActivityData ActivityData::ForThread(const PlatformThreadHandle& handle) {
-  ThreadRef thread_ref;
-  thread_ref.as_id = 0;  // Zero the union in case other is smaller.
-#if defined(OS_WIN)
-  thread_ref.as_tid = ::GetThreadId(handle.platform_handle());
-#elif defined(OS_POSIX)
-  thread_ref.as_handle = handle.platform_handle();
-#endif
-  return ForThread(thread_ref.as_id);
-}
-
-ActivityTrackerMemoryAllocator::ActivityTrackerMemoryAllocator(
-    PersistentMemoryAllocator* allocator,
-    uint32_t object_type,
-    uint32_t object_free_type,
-    size_t object_size,
-    size_t cache_size,
-    bool make_iterable)
-    : allocator_(allocator),
-      object_type_(object_type),
-      object_free_type_(object_free_type),
-      object_size_(object_size),
-      cache_size_(cache_size),
-      make_iterable_(make_iterable),
-      iterator_(allocator),
-      cache_values_(new Reference[cache_size]),
-      cache_used_(0) {
-  DCHECK(allocator);
-}
-
-ActivityTrackerMemoryAllocator::~ActivityTrackerMemoryAllocator() = default;
-
-ActivityTrackerMemoryAllocator::Reference
-ActivityTrackerMemoryAllocator::GetObjectReference() {
-  // First see if there is a cached value that can be returned. This is much
-  // faster than searching the memory system for free blocks.
-  while (cache_used_ > 0) {
-    Reference cached = cache_values_[--cache_used_];
-    // Change the type of the cached object to the proper type and return it.
-    // If the type-change fails that means another thread has taken this from
-    // under us (via the search below) so ignore it and keep trying. Don't
-    // clear the memory because that was done when the type was made "free".
-    if (allocator_->ChangeType(cached, object_type_, object_free_type_, false))
-      return cached;
-  }
-
-  // Fetch the next "free" object from persistent memory. Rather than restart
-  // the iterator at the head each time and likely waste time going again
-  // through objects that aren't relevant, the iterator continues from where
-  // it last left off and is only reset when the end is reached. If the
-  // returned reference matches |last|, then it has wrapped without finding
-  // anything.
-  const Reference last = iterator_.GetLast();
-  while (true) {
-    uint32_t type;
-    Reference found = iterator_.GetNext(&type);
-    if (found && type == object_free_type_) {
-      // Found a free object. Change it to the proper type and return it. If
-      // the type-change fails that means another thread has taken this from
-      // under us so ignore it and keep trying.
-      if (allocator_->ChangeType(found, object_type_, object_free_type_, false))
-        return found;
-    }
-    if (found == last) {
-      // Wrapped. No desired object was found.
-      break;
-    }
-    if (!found) {
-      // Reached end; start over at the beginning.
-      iterator_.Reset();
-    }
-  }
-
-  // No free block was found so instead allocate a new one.
-  Reference allocated = allocator_->Allocate(object_size_, object_type_);
-  if (allocated && make_iterable_)
-    allocator_->MakeIterable(allocated);
-  return allocated;
-}
-
-void ActivityTrackerMemoryAllocator::ReleaseObjectReference(Reference ref) {
-  // Mark object as free.
-  bool success = allocator_->ChangeType(ref, object_free_type_, object_type_,
-                                        /*clear=*/true);
-  DCHECK(success);
-
-  // Add this reference to our "free" cache if there is space. If not, the type
-  // has still been changed to indicate that it is free so this (or another)
-  // thread can find it, albeit more slowly, using the iteration method above.
-  if (cache_used_ < cache_size_)
-    cache_values_[cache_used_++] = ref;
-}
-
-// static
-void Activity::FillFrom(Activity* activity,
-                        const void* program_counter,
-                        const void* origin,
-                        Type type,
-                        const ActivityData& data) {
-  activity->time_internal = base::TimeTicks::Now().ToInternalValue();
-  activity->calling_address = reinterpret_cast<uintptr_t>(program_counter);
-  activity->origin_address = reinterpret_cast<uintptr_t>(origin);
-  activity->activity_type = type;
-  activity->data = data;
-
-#if (!defined(OS_NACL) && DCHECK_IS_ON()) || defined(ADDRESS_SANITIZER)
-  // Create a stacktrace from the current location and get the addresses for
-  // improved debuggability.
-  StackTrace stack_trace;
-  size_t stack_depth;
-  const void* const* stack_addrs = stack_trace.Addresses(&stack_depth);
-  // Copy the stack addresses, ignoring the first one (here).
-  size_t i;
-  for (i = 1; i < stack_depth && i < kActivityCallStackSize; ++i) {
-    activity->call_stack[i - 1] = reinterpret_cast<uintptr_t>(stack_addrs[i]);
-  }
-  activity->call_stack[i - 1] = 0;
-#else
-  activity->call_stack[0] = 0;
-#endif
-}
-
-ActivityUserData::TypedValue::TypedValue() = default;
-ActivityUserData::TypedValue::TypedValue(const TypedValue& other) = default;
-ActivityUserData::TypedValue::~TypedValue() = default;
-
-StringPiece ActivityUserData::TypedValue::Get() const {
-  DCHECK_EQ(RAW_VALUE, type_);
-  return long_value_;
-}
-
-StringPiece ActivityUserData::TypedValue::GetString() const {
-  DCHECK_EQ(STRING_VALUE, type_);
-  return long_value_;
-}
-
-bool ActivityUserData::TypedValue::GetBool() const {
-  DCHECK_EQ(BOOL_VALUE, type_);
-  return short_value_ != 0;
-}
-
-char ActivityUserData::TypedValue::GetChar() const {
-  DCHECK_EQ(CHAR_VALUE, type_);
-  return static_cast<char>(short_value_);
-}
-
-int64_t ActivityUserData::TypedValue::GetInt() const {
-  DCHECK_EQ(SIGNED_VALUE, type_);
-  return static_cast<int64_t>(short_value_);
-}
-
-uint64_t ActivityUserData::TypedValue::GetUint() const {
-  DCHECK_EQ(UNSIGNED_VALUE, type_);
-  return static_cast<uint64_t>(short_value_);
-}
-
-StringPiece ActivityUserData::TypedValue::GetReference() const {
-  DCHECK_EQ(RAW_VALUE_REFERENCE, type_);
-  return ref_value_;
-}
-
-StringPiece ActivityUserData::TypedValue::GetStringReference() const {
-  DCHECK_EQ(STRING_VALUE_REFERENCE, type_);
-  return ref_value_;
-}
-
-// These are required because std::atomic is (currently) not a POD type and
-// thus clang requires explicit out-of-line constructors and destructors even
-// when they do nothing.
-ActivityUserData::ValueInfo::ValueInfo() = default;
-ActivityUserData::ValueInfo::ValueInfo(ValueInfo&&) = default;
-ActivityUserData::ValueInfo::~ValueInfo() = default;
-ActivityUserData::MemoryHeader::MemoryHeader() = default;
-ActivityUserData::MemoryHeader::~MemoryHeader() = default;
-ActivityUserData::FieldHeader::FieldHeader() = default;
-ActivityUserData::FieldHeader::~FieldHeader() = default;
-
-ActivityUserData::ActivityUserData() : ActivityUserData(nullptr, 0, -1) {}
-
-ActivityUserData::ActivityUserData(void* memory, size_t size, int64_t pid)
-    : memory_(reinterpret_cast<char*>(memory)),
-      available_(RoundDownToAlignment(size, kMemoryAlignment)),
-      header_(reinterpret_cast<MemoryHeader*>(memory)),
-      orig_data_id(0),
-      orig_process_id(0),
-      orig_create_stamp(0) {
-  // It's possible that no user data is being stored.
-  if (!memory_)
-    return;
-
-  static_assert(0 == sizeof(MemoryHeader) % kMemoryAlignment, "invalid header");
-  DCHECK_LT(sizeof(MemoryHeader), available_);
-  if (header_->owner.data_id.load(std::memory_order_acquire) == 0)
-    header_->owner.Release_Initialize(pid);
-  memory_ += sizeof(MemoryHeader);
-  available_ -= sizeof(MemoryHeader);
-
-  // Make a copy of identifying information for later comparison.
-  *const_cast<uint32_t*>(&orig_data_id) =
-      header_->owner.data_id.load(std::memory_order_acquire);
-  *const_cast<int64_t*>(&orig_process_id) = header_->owner.process_id;
-  *const_cast<int64_t*>(&orig_create_stamp) = header_->owner.create_stamp;
-
-  // If there is already data present, load that. This allows the same class
-  // to be used for analysis through snapshots.
-  ImportExistingData();
-}
-
-ActivityUserData::~ActivityUserData() = default;
-
-bool ActivityUserData::CreateSnapshot(Snapshot* output_snapshot) const {
-  DCHECK(output_snapshot);
-  DCHECK(output_snapshot->empty());
-
-  // Find any new data that may have been added by an active instance of this
-  // class that is adding records.
-  ImportExistingData();
-
-  // Add all the values to the snapshot.
-  for (const auto& entry : values_) {
-    TypedValue value;
-    const size_t size = entry.second.size_ptr->load(std::memory_order_acquire);
-    value.type_ = entry.second.type;
-    DCHECK_GE(entry.second.extent, size);
-
-    switch (entry.second.type) {
-      case RAW_VALUE:
-      case STRING_VALUE:
-        value.long_value_ =
-            std::string(reinterpret_cast<char*>(entry.second.memory), size);
-        break;
-      case RAW_VALUE_REFERENCE:
-      case STRING_VALUE_REFERENCE: {
-        ReferenceRecord* ref =
-            reinterpret_cast<ReferenceRecord*>(entry.second.memory);
-        value.ref_value_ = StringPiece(
-            reinterpret_cast<char*>(static_cast<uintptr_t>(ref->address)),
-            static_cast<size_t>(ref->size));
-      } break;
-      case BOOL_VALUE:
-      case CHAR_VALUE:
-        value.short_value_ = *reinterpret_cast<char*>(entry.second.memory);
-        break;
-      case SIGNED_VALUE:
-      case UNSIGNED_VALUE:
-        value.short_value_ = *reinterpret_cast<uint64_t*>(entry.second.memory);
-        break;
-      case END_OF_VALUES:  // Included for completeness purposes.
-        NOTREACHED();
-    }
-    auto inserted = output_snapshot->insert(
-        std::make_pair(entry.second.name.as_string(), std::move(value)));
-    DCHECK(inserted.second);  // True if inserted, false if existed.
-  }
-
-  // Another import attempt will validate that the underlying memory has not
-  // been reused for another purpose. Entries added since the first import
-  // will be ignored here but will be returned if another snapshot is created.
-  ImportExistingData();
-  if (!memory_) {
-    output_snapshot->clear();
-    return false;
-  }
-
-  // Successful snapshot.
-  return true;
-}
-
-const void* ActivityUserData::GetBaseAddress() const {
-  // The |memory_| pointer advances as elements are written but the |header_|
-  // value is always at the start of the block so just return that.
-  return header_;
-}
-
-void ActivityUserData::SetOwningProcessIdForTesting(int64_t pid,
-                                                    int64_t stamp) {
-  if (!header_)
-    return;
-  header_->owner.SetOwningProcessIdForTesting(pid, stamp);
-}
-
-// static
-bool ActivityUserData::GetOwningProcessId(const void* memory,
-                                          int64_t* out_id,
-                                          int64_t* out_stamp) {
-  const MemoryHeader* header = reinterpret_cast<const MemoryHeader*>(memory);
-  return OwningProcess::GetOwningProcessId(&header->owner, out_id, out_stamp);
-}
-
-void ActivityUserData::Set(StringPiece name,
-                           ValueType type,
-                           const void* memory,
-                           size_t size) {
-  DCHECK_GE(std::numeric_limits<uint8_t>::max(), name.length());
-  size = std::min(std::numeric_limits<uint16_t>::max() - (kMemoryAlignment - 1),
-                  size);
-
-  // It's possible that no user data is being stored.
-  if (!memory_)
-    return;
-
-  // The storage of a name is limited so use that limit during lookup.
-  if (name.length() > kMaxUserDataNameLength)
-    name.set(name.data(), kMaxUserDataNameLength);
-
-  ValueInfo* info;
-  auto existing = values_.find(name);
-  if (existing != values_.end()) {
-    info = &existing->second;
-  } else {
-    // The name size is limited to what can be held in a single byte but
-    // because there are not alignment constraints on strings, it's set tight
-    // against the header. Its extent (the reserved space, even if it's not
-    // all used) is calculated so that, when pressed against the header, the
-    // following field will be aligned properly.
-    size_t name_size = name.length();
-    size_t name_extent =
-        RoundUpToAlignment(sizeof(FieldHeader) + name_size, kMemoryAlignment) -
-        sizeof(FieldHeader);
-    size_t value_extent = RoundUpToAlignment(size, kMemoryAlignment);
-
-    // The "base size" is the size of the header and (padded) string key. Stop
-    // now if there's not room enough for even this.
-    size_t base_size = sizeof(FieldHeader) + name_extent;
-    if (base_size > available_)
-      return;
-
-    // The "full size" is the size for storing the entire value.
-    size_t full_size = std::min(base_size + value_extent, available_);
-
-    // If the value is actually a single byte, see if it can be stuffed at the
-    // end of the name extent rather than wasting kMemoryAlignment bytes.
-    if (size == 1 && name_extent > name_size) {
-      full_size = base_size;
-      --name_extent;
-      --base_size;
-    }
-
-    // Truncate the stored size to the amount of available memory. Stop now if
-    // there's not any room for even part of the value.
-    if (size != 0) {
-      size = std::min(full_size - base_size, size);
-      if (size == 0)
-        return;
-    }
-
-    // Allocate a chunk of memory.
-    FieldHeader* header = reinterpret_cast<FieldHeader*>(memory_);
-    memory_ += full_size;
-    available_ -= full_size;
-
-    // Datafill the header and name records. Memory must be zeroed. The |type|
-    // is written last, atomically, to release all the other values.
-    DCHECK_EQ(END_OF_VALUES, header->type.load(std::memory_order_relaxed));
-    DCHECK_EQ(0, header->value_size.load(std::memory_order_relaxed));
-    header->name_size = static_cast<uint8_t>(name_size);
-    header->record_size = full_size;
-    char* name_memory = reinterpret_cast<char*>(header) + sizeof(FieldHeader);
-    void* value_memory =
-        reinterpret_cast<char*>(header) + sizeof(FieldHeader) + name_extent;
-    memcpy(name_memory, name.data(), name_size);
-    header->type.store(type, std::memory_order_release);
-
-    // Create an entry in |values_| so that this field can be found and changed
-    // later on without having to allocate new entries.
-    StringPiece persistent_name(name_memory, name_size);
-    auto inserted =
-        values_.insert(std::make_pair(persistent_name, ValueInfo()));
-    DCHECK(inserted.second);  // True if inserted, false if existed.
-    info = &inserted.first->second;
-    info->name = persistent_name;
-    info->memory = value_memory;
-    info->size_ptr = &header->value_size;
-    info->extent = full_size - sizeof(FieldHeader) - name_extent;
-    info->type = type;
-  }
-
-  // Copy the value data to storage. The |size| is written last, atomically, to
-  // release the copied data. Until then, a parallel reader will just ignore
-  // records with a zero size.
-  DCHECK_EQ(type, info->type);
-  size = std::min(size, info->extent);
-  info->size_ptr->store(0, std::memory_order_seq_cst);
-  memcpy(info->memory, memory, size);
-  info->size_ptr->store(size, std::memory_order_release);
-}
-
-void ActivityUserData::SetReference(StringPiece name,
-                                    ValueType type,
-                                    const void* memory,
-                                    size_t size) {
-  ReferenceRecord rec;
-  rec.address = reinterpret_cast<uintptr_t>(memory);
-  rec.size = size;
-  Set(name, type, &rec, sizeof(rec));
-}
-
-void ActivityUserData::ImportExistingData() const {
-  // It's possible that no user data is being stored.
-  if (!memory_)
-    return;
-
-  while (available_ > sizeof(FieldHeader)) {
-    FieldHeader* header = reinterpret_cast<FieldHeader*>(memory_);
-    ValueType type =
-        static_cast<ValueType>(header->type.load(std::memory_order_acquire));
-    if (type == END_OF_VALUES)
-      return;
-    if (header->record_size > available_)
-      return;
-
-    size_t value_offset = RoundUpToAlignment(
-        sizeof(FieldHeader) + header->name_size, kMemoryAlignment);
-    if (header->record_size == value_offset &&
-        header->value_size.load(std::memory_order_relaxed) == 1) {
-      value_offset -= 1;
-    }
-    if (value_offset + header->value_size > header->record_size)
-      return;
-
-    ValueInfo info;
-    info.name = StringPiece(memory_ + sizeof(FieldHeader), header->name_size);
-    info.type = type;
-    info.memory = memory_ + value_offset;
-    info.size_ptr = &header->value_size;
-    info.extent = header->record_size - value_offset;
-
-    StringPiece key(info.name);
-    values_.insert(std::make_pair(key, std::move(info)));
-
-    memory_ += header->record_size;
-    available_ -= header->record_size;
-  }
-
-  // Check if memory has been completely reused.
-  if (header_->owner.data_id.load(std::memory_order_acquire) != orig_data_id ||
-      header_->owner.process_id != orig_process_id ||
-      header_->owner.create_stamp != orig_create_stamp) {
-    memory_ = nullptr;
-    values_.clear();
-  }
-}
-
-// This information is kept for every thread that is tracked. It is filled
-// the very first time the thread is seen. All fields must be of exact sizes
-// so there is no issue moving between 32 and 64-bit builds.
-struct ThreadActivityTracker::Header {
-  // Defined in .h for analyzer access. Increment this if structure changes!
-  static constexpr uint32_t kPersistentTypeId =
-      GlobalActivityTracker::kTypeIdActivityTracker;
-
-  // Expected size for 32/64-bit check.
-  static constexpr size_t kExpectedInstanceSize =
-      OwningProcess::kExpectedInstanceSize + Activity::kExpectedInstanceSize +
-      72;
-
-  // This information uniquely identifies a process.
-  OwningProcess owner;
-
-  // The thread-id (thread_ref.as_id) to which this data belongs. This number
-  // is not guaranteed to mean anything but combined with the process-id from
-  // OwningProcess is unique among all active trackers.
-  ThreadRef thread_ref;
-
-  // The start-time and start-ticks when the data was created. Each activity
-  // record has a |time_internal| value that can be converted to a "wall time"
-  // with these two values.
-  int64_t start_time;
-  int64_t start_ticks;
-
-  // The number of Activity slots (spaces that can hold an Activity) that
-  // immediately follow this structure in memory.
-  uint32_t stack_slots;
-
-  // Some padding to keep everything 64-bit aligned.
-  uint32_t padding;
-
-  // The current depth of the stack. This may be greater than the number of
-  // slots. If the depth exceeds the number of slots, the newest entries
-  // won't be recorded.
-  std::atomic<uint32_t> current_depth;
-
-  // A memory location used to indicate if changes have been made to the data
-  // that would invalidate an in-progress read of its contents. The active
-  // tracker will increment the value whenever something gets popped from the
-  // stack. A monitoring tracker can check the value before and after access
-  // to know, if it's still the same, that the contents didn't change while
-  // being copied.
-  std::atomic<uint32_t> data_version;
-
-  // The last "exception" activity. This can't be stored on the stack because
-  // that could get popped as things unwind.
-  Activity last_exception;
-
-  // The name of the thread (up to a maximum length). Dynamic-length names
-  // are not practical since the memory has to come from the same persistent
-  // allocator that holds this structure and to which this object has no
-  // reference.
-  char thread_name[32];
-};
-
-ThreadActivityTracker::Snapshot::Snapshot() = default;
-ThreadActivityTracker::Snapshot::~Snapshot() = default;
-
-ThreadActivityTracker::ScopedActivity::ScopedActivity(
-    ThreadActivityTracker* tracker,
-    const void* program_counter,
-    const void* origin,
-    Activity::Type type,
-    const ActivityData& data)
-    : tracker_(tracker) {
-  if (tracker_)
-    activity_id_ = tracker_->PushActivity(program_counter, origin, type, data);
-}
-
-ThreadActivityTracker::ScopedActivity::~ScopedActivity() {
-  if (tracker_)
-    tracker_->PopActivity(activity_id_);
-}
-
-void ThreadActivityTracker::ScopedActivity::ChangeTypeAndData(
-    Activity::Type type,
-    const ActivityData& data) {
-  if (tracker_)
-    tracker_->ChangeActivity(activity_id_, type, data);
-}
-
-ThreadActivityTracker::ThreadActivityTracker(void* base, size_t size)
-    : header_(static_cast<Header*>(base)),
-      stack_(reinterpret_cast<Activity*>(reinterpret_cast<char*>(base) +
-                                         sizeof(Header))),
-#if DCHECK_IS_ON()
-      thread_id_(PlatformThreadRef()),
-#endif
-      stack_slots_(
-          static_cast<uint32_t>((size - sizeof(Header)) / sizeof(Activity))) {
-
-  // Verify the parameters but fail gracefully if they're not valid so that
-  // production code based on external inputs will not crash.  IsValid() will
-  // return false in this case.
-  if (!base ||
-      // Ensure there is enough space for the header and at least a few records.
-      size < sizeof(Header) + kMinStackDepth * sizeof(Activity) ||
-      // Ensure that the |stack_slots_| calculation didn't overflow.
-      (size - sizeof(Header)) / sizeof(Activity) >
-          std::numeric_limits<uint32_t>::max()) {
-    NOTREACHED();
-    return;
-  }
-
-  // Ensure that the thread reference doesn't exceed the size of the ID number.
-  // This won't compile at the global scope because Header is a private struct.
-  static_assert(
-      sizeof(header_->thread_ref) == sizeof(header_->thread_ref.as_id),
-      "PlatformThreadHandle::Handle is too big to hold in 64-bit ID");
-
-  // Ensure that the alignment of Activity.data is properly aligned to a
-  // 64-bit boundary so there are no interoperability-issues across cpu
-  // architectures.
-  static_assert(offsetof(Activity, data) % sizeof(uint64_t) == 0,
-                "ActivityData.data is not 64-bit aligned");
-
-  // Provided memory should either be completely initialized or all zeros.
-  if (header_->owner.data_id.load(std::memory_order_relaxed) == 0) {
-    // This is a new file. Double-check other fields and then initialize.
-    DCHECK_EQ(0, header_->owner.process_id);
-    DCHECK_EQ(0, header_->owner.create_stamp);
-    DCHECK_EQ(0, header_->thread_ref.as_id);
-    DCHECK_EQ(0, header_->start_time);
-    DCHECK_EQ(0, header_->start_ticks);
-    DCHECK_EQ(0U, header_->stack_slots);
-    DCHECK_EQ(0U, header_->current_depth.load(std::memory_order_relaxed));
-    DCHECK_EQ(0U, header_->data_version.load(std::memory_order_relaxed));
-    DCHECK_EQ(0, stack_[0].time_internal);
-    DCHECK_EQ(0U, stack_[0].origin_address);
-    DCHECK_EQ(0U, stack_[0].call_stack[0]);
-    DCHECK_EQ(0U, stack_[0].data.task.sequence_id);
-
-#if defined(OS_WIN)
-    header_->thread_ref.as_tid = PlatformThread::CurrentId();
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
-    header_->thread_ref.as_handle =
-        PlatformThread::CurrentHandle().platform_handle();
-#endif
-
-    header_->start_time = base::Time::Now().ToInternalValue();
-    header_->start_ticks = base::TimeTicks::Now().ToInternalValue();
-    header_->stack_slots = stack_slots_;
-    strlcpy(header_->thread_name, PlatformThread::GetName(),
-            sizeof(header_->thread_name));
-
-    // This is done last so as to guarantee that everything above is "released"
-    // by the time this value gets written.
-    header_->owner.Release_Initialize();
-
-    valid_ = true;
-    DCHECK(IsValid());
-  } else {
-    // This is a file with existing data. Perform basic consistency checks.
-    valid_ = true;
-    valid_ = IsValid();
-  }
-}
-
-ThreadActivityTracker::~ThreadActivityTracker() = default;
-
-ThreadActivityTracker::ActivityId ThreadActivityTracker::PushActivity(
-    const void* program_counter,
-    const void* origin,
-    Activity::Type type,
-    const ActivityData& data) {
-  // A thread-checker creates a lock to check the thread-id which means
-  // re-entry into this code if lock acquisitions are being tracked.
-  DCHECK(type == Activity::ACT_LOCK_ACQUIRE || CalledOnValidThread());
-
-  // Get the current depth of the stack. No access to other memory guarded
-  // by this variable is done here so a "relaxed" load is acceptable.
-  uint32_t depth = header_->current_depth.load(std::memory_order_relaxed);
-
-  // Handle the case where the stack depth has exceeded the storage capacity.
-  // Extra entries will be lost leaving only the base of the stack.
-  if (depth >= stack_slots_) {
-    // Since no other threads modify the data, no compare/exchange is needed.
-    // Since no other memory is being modified, a "relaxed" store is acceptable.
-    header_->current_depth.store(depth + 1, std::memory_order_relaxed);
-    return depth;
-  }
-
-  // Get a pointer to the next activity and load it. No atomicity is required
-  // here because the memory is known only to this thread. It will be made
-  // known to other threads once the depth is incremented.
-  Activity::FillFrom(&stack_[depth], program_counter, origin, type, data);
-
-  // Save the incremented depth. Because this guards |activity| memory filled
-  // above that may be read by another thread once the recorded depth changes,
-  // a "release" store is required.
-  header_->current_depth.store(depth + 1, std::memory_order_release);
-
-  // The current depth is used as the activity ID because it simply identifies
-  // an entry. Once an entry is pop'd, it's okay to reuse the ID.
-  return depth;
-}
-
-void ThreadActivityTracker::ChangeActivity(ActivityId id,
-                                           Activity::Type type,
-                                           const ActivityData& data) {
-  DCHECK(CalledOnValidThread());
-  DCHECK(type != Activity::ACT_NULL || &data != &kNullActivityData);
-  DCHECK_LT(id, header_->current_depth.load(std::memory_order_acquire));
-
-  // Update the information if it is being recorded (i.e. within slot limit).
-  if (id < stack_slots_) {
-    Activity* activity = &stack_[id];
-
-    if (type != Activity::ACT_NULL) {
-      DCHECK_EQ(activity->activity_type & Activity::ACT_CATEGORY_MASK,
-                type & Activity::ACT_CATEGORY_MASK);
-      activity->activity_type = type;
-    }
-
-    if (&data != &kNullActivityData)
-      activity->data = data;
-  }
-}
-
-void ThreadActivityTracker::PopActivity(ActivityId id) {
-  // Do an atomic decrement of the depth. No changes to stack entries guarded
-  // by this variable are done here so a "relaxed" operation is acceptable.
-  // |depth| will receive the value BEFORE it was modified which means the
-  // return value must also be decremented. The slot will be "free" after
-  // this call but since only a single thread can access this object, the
-  // data will remain valid until this method returns or calls outside.
-  uint32_t depth =
-      header_->current_depth.fetch_sub(1, std::memory_order_relaxed) - 1;
-
-  // Validate that everything is running correctly.
-  DCHECK_EQ(id, depth);
-
-  // A thread-checker creates a lock to check the thread-id which means
-  // re-entry into this code if lock acquisitions are being tracked.
-  DCHECK(stack_[depth].activity_type == Activity::ACT_LOCK_ACQUIRE ||
-         CalledOnValidThread());
-
-  // The stack has shrunk meaning that some other thread trying to copy the
-  // contents for reporting purposes could get bad data. Increment the data
-  // version so that it con tell that things have changed. This needs to
-  // happen after the atomic |depth| operation above so a "release" store
-  // is required.
-  header_->data_version.fetch_add(1, std::memory_order_release);
-}
-
-std::unique_ptr<ActivityUserData> ThreadActivityTracker::GetUserData(
-    ActivityId id,
-    ActivityTrackerMemoryAllocator* allocator) {
-  // Don't allow user data for lock acquisition as recursion may occur.
-  if (stack_[id].activity_type == Activity::ACT_LOCK_ACQUIRE) {
-    NOTREACHED();
-    return std::make_unique<ActivityUserData>();
-  }
-
-  // User-data is only stored for activities actually held in the stack.
-  if (id >= stack_slots_)
-    return std::make_unique<ActivityUserData>();
-
-  // Create and return a real UserData object.
-  return CreateUserDataForActivity(&stack_[id], allocator);
-}
-
-bool ThreadActivityTracker::HasUserData(ActivityId id) {
-  // User-data is only stored for activities actually held in the stack.
-  return (id < stack_slots_ && stack_[id].user_data_ref);
-}
-
-void ThreadActivityTracker::ReleaseUserData(
-    ActivityId id,
-    ActivityTrackerMemoryAllocator* allocator) {
-  // User-data is only stored for activities actually held in the stack.
-  if (id < stack_slots_ && stack_[id].user_data_ref) {
-    allocator->ReleaseObjectReference(stack_[id].user_data_ref);
-    stack_[id].user_data_ref = 0;
-  }
-}
-
-void ThreadActivityTracker::RecordExceptionActivity(const void* program_counter,
-                                                    const void* origin,
-                                                    Activity::Type type,
-                                                    const ActivityData& data) {
-  // A thread-checker creates a lock to check the thread-id which means
-  // re-entry into this code if lock acquisitions are being tracked.
-  DCHECK(CalledOnValidThread());
-
-  // Fill the reusable exception activity.
-  Activity::FillFrom(&header_->last_exception, program_counter, origin, type,
-                     data);
-
-  // The data has changed meaning that some other thread trying to copy the
-  // contents for reporting purposes could get bad data.
-  header_->data_version.fetch_add(1, std::memory_order_relaxed);
-}
-
-bool ThreadActivityTracker::IsValid() const {
-  if (header_->owner.data_id.load(std::memory_order_acquire) == 0 ||
-      header_->owner.process_id == 0 || header_->thread_ref.as_id == 0 ||
-      header_->start_time == 0 || header_->start_ticks == 0 ||
-      header_->stack_slots != stack_slots_ ||
-      header_->thread_name[sizeof(header_->thread_name) - 1] != '\0') {
-    return false;
-  }
-
-  return valid_;
-}
-
-bool ThreadActivityTracker::CreateSnapshot(Snapshot* output_snapshot) const {
-  DCHECK(output_snapshot);
-
-  // There is no "called on valid thread" check for this method as it can be
-  // called from other threads or even other processes. It is also the reason
-  // why atomic operations must be used in certain places above.
-
-  // It's possible for the data to change while reading it in such a way that it
-  // invalidates the read. Make several attempts but don't try forever.
-  const int kMaxAttempts = 10;
-  uint32_t depth;
-
-  // Stop here if the data isn't valid.
-  if (!IsValid())
-    return false;
-
-  // Allocate the maximum size for the stack so it doesn't have to be done
-  // during the time-sensitive snapshot operation. It is shrunk once the
-  // actual size is known.
-  output_snapshot->activity_stack.reserve(stack_slots_);
-
-  for (int attempt = 0; attempt < kMaxAttempts; ++attempt) {
-    // Remember the data IDs to ensure nothing is replaced during the snapshot
-    // operation. Use "acquire" so that all the non-atomic fields of the
-    // structure are valid (at least at the current moment in time).
-    const uint32_t starting_id =
-        header_->owner.data_id.load(std::memory_order_acquire);
-    const int64_t starting_create_stamp = header_->owner.create_stamp;
-    const int64_t starting_process_id = header_->owner.process_id;
-    const int64_t starting_thread_id = header_->thread_ref.as_id;
-
-    // Note the current |data_version| so it's possible to detect at the end
-    // that nothing has changed since copying the data began. A "cst" operation
-    // is required to ensure it occurs before everything else. Using "cst"
-    // memory ordering is relatively expensive but this is only done during
-    // analysis so doesn't directly affect the worker threads.
-    const uint32_t pre_version =
-        header_->data_version.load(std::memory_order_seq_cst);
-
-    // Fetching the current depth also "acquires" the contents of the stack.
-    depth = header_->current_depth.load(std::memory_order_acquire);
-    uint32_t count = std::min(depth, stack_slots_);
-    output_snapshot->activity_stack.resize(count);
-    if (count > 0) {
-      // Copy the existing contents. Memcpy is used for speed.
-      memcpy(&output_snapshot->activity_stack[0], stack_,
-             count * sizeof(Activity));
-    }
-
-    // Capture the last exception.
-    memcpy(&output_snapshot->last_exception, &header_->last_exception,
-           sizeof(Activity));
-
-    // TODO(bcwhite): Snapshot other things here.
-
-    // Retry if something changed during the copy. A "cst" operation ensures
-    // it must happen after all the above operations.
-    if (header_->data_version.load(std::memory_order_seq_cst) != pre_version)
-      continue;
-
-    // Stack copied. Record it's full depth.
-    output_snapshot->activity_stack_depth = depth;
-
-    // Get the general thread information.
-    output_snapshot->thread_name =
-        std::string(header_->thread_name, sizeof(header_->thread_name) - 1);
-    output_snapshot->create_stamp = header_->owner.create_stamp;
-    output_snapshot->thread_id = header_->thread_ref.as_id;
-    output_snapshot->process_id = header_->owner.process_id;
-
-    // All characters of the thread-name buffer were copied so as to not break
-    // if the trailing NUL were missing. Now limit the length if the actual
-    // name is shorter.
-    output_snapshot->thread_name.resize(
-        strlen(output_snapshot->thread_name.c_str()));
-
-    // If the data ID has changed then the tracker has exited and the memory
-    // reused by a new one. Try again.
-    if (header_->owner.data_id.load(std::memory_order_seq_cst) != starting_id ||
-        output_snapshot->create_stamp != starting_create_stamp ||
-        output_snapshot->process_id != starting_process_id ||
-        output_snapshot->thread_id != starting_thread_id) {
-      continue;
-    }
-
-    // Only successful if the data is still valid once everything is done since
-    // it's possible for the thread to end somewhere in the middle and all its
-    // values become garbage.
-    if (!IsValid())
-      return false;
-
-    // Change all the timestamps in the activities from "ticks" to "wall" time.
-    const Time start_time = Time::FromInternalValue(header_->start_time);
-    const int64_t start_ticks = header_->start_ticks;
-    for (Activity& activity : output_snapshot->activity_stack) {
-      activity.time_internal =
-          WallTimeFromTickTime(start_ticks, activity.time_internal, start_time)
-              .ToInternalValue();
-    }
-    output_snapshot->last_exception.time_internal =
-        WallTimeFromTickTime(start_ticks,
-                             output_snapshot->last_exception.time_internal,
-                             start_time)
-            .ToInternalValue();
-
-    // Success!
-    return true;
-  }
-
-  // Too many attempts.
-  return false;
-}
-
-const void* ThreadActivityTracker::GetBaseAddress() {
-  return header_;
-}
-
-uint32_t ThreadActivityTracker::GetDataVersionForTesting() {
-  return header_->data_version.load(std::memory_order_relaxed);
-}
-
-void ThreadActivityTracker::SetOwningProcessIdForTesting(int64_t pid,
-                                                         int64_t stamp) {
-  header_->owner.SetOwningProcessIdForTesting(pid, stamp);
-}
-
-// static
-bool ThreadActivityTracker::GetOwningProcessId(const void* memory,
-                                               int64_t* out_id,
-                                               int64_t* out_stamp) {
-  const Header* header = reinterpret_cast<const Header*>(memory);
-  return OwningProcess::GetOwningProcessId(&header->owner, out_id, out_stamp);
-}
-
-// static
-size_t ThreadActivityTracker::SizeForStackDepth(int stack_depth) {
-  return static_cast<size_t>(stack_depth) * sizeof(Activity) + sizeof(Header);
-}
-
-bool ThreadActivityTracker::CalledOnValidThread() {
-#if DCHECK_IS_ON()
-  return thread_id_ == PlatformThreadRef();
-#else
-  return true;
-#endif
-}
-
-std::unique_ptr<ActivityUserData>
-ThreadActivityTracker::CreateUserDataForActivity(
-    Activity* activity,
-    ActivityTrackerMemoryAllocator* allocator) {
-  DCHECK_EQ(0U, activity->user_data_ref);
-
-  PersistentMemoryAllocator::Reference ref = allocator->GetObjectReference();
-  void* memory = allocator->GetAsArray<char>(ref, kUserDataSize);
-  if (memory) {
-    std::unique_ptr<ActivityUserData> user_data =
-        std::make_unique<ActivityUserData>(memory, kUserDataSize);
-    activity->user_data_ref = ref;
-    activity->user_data_id = user_data->id();
-    return user_data;
-  }
-
-  // Return a dummy object that will still accept (but ignore) Set() calls.
-  return std::make_unique<ActivityUserData>();
-}
-
-// The instantiation of the GlobalActivityTracker object.
-// The object held here will obviously not be destructed at process exit
-// but that's best since PersistentMemoryAllocator objects (that underlie
-// GlobalActivityTracker objects) are explicitly forbidden from doing anything
-// essential at exit anyway due to the fact that they depend on data managed
-// elsewhere and which could be destructed first. An AtomicWord is used instead
-// of std::atomic because the latter can create global ctors and dtors.
-subtle::AtomicWord GlobalActivityTracker::g_tracker_ = 0;
-
-GlobalActivityTracker::ModuleInfo::ModuleInfo() = default;
-GlobalActivityTracker::ModuleInfo::ModuleInfo(ModuleInfo&& rhs) = default;
-GlobalActivityTracker::ModuleInfo::ModuleInfo(const ModuleInfo& rhs) = default;
-GlobalActivityTracker::ModuleInfo::~ModuleInfo() = default;
-
-GlobalActivityTracker::ModuleInfo& GlobalActivityTracker::ModuleInfo::operator=(
-    ModuleInfo&& rhs) = default;
-GlobalActivityTracker::ModuleInfo& GlobalActivityTracker::ModuleInfo::operator=(
-    const ModuleInfo& rhs) = default;
-
-GlobalActivityTracker::ModuleInfoRecord::ModuleInfoRecord() = default;
-GlobalActivityTracker::ModuleInfoRecord::~ModuleInfoRecord() = default;
-
-bool GlobalActivityTracker::ModuleInfoRecord::DecodeTo(
-    GlobalActivityTracker::ModuleInfo* info,
-    size_t record_size) const {
-  // Get the current "changes" indicator, acquiring all the other values.
-  uint32_t current_changes = changes.load(std::memory_order_acquire);
-
-  // Copy out the dynamic information.
-  info->is_loaded = loaded != 0;
-  info->address = static_cast<uintptr_t>(address);
-  info->load_time = load_time;
-
-  // Check to make sure no information changed while being read. A "seq-cst"
-  // operation is expensive but is only done during analysis and it's the only
-  // way to ensure this occurs after all the accesses above. If changes did
-  // occur then return a "not loaded" result so that |size| and |address|
-  // aren't expected to be accurate.
-  if ((current_changes & kModuleInformationChanging) != 0 ||
-      changes.load(std::memory_order_seq_cst) != current_changes) {
-    info->is_loaded = false;
-  }
-
-  // Copy out the static information. These never change so don't have to be
-  // protected by the atomic |current_changes| operations.
-  info->size = static_cast<size_t>(size);
-  info->timestamp = timestamp;
-  info->age = age;
-  memcpy(info->identifier, identifier, sizeof(info->identifier));
-
-  if (offsetof(ModuleInfoRecord, pickle) + pickle_size > record_size)
-    return false;
-  Pickle pickler(pickle, pickle_size);
-  PickleIterator iter(pickler);
-  return iter.ReadString(&info->file) && iter.ReadString(&info->debug_file);
-}
-
-GlobalActivityTracker::ModuleInfoRecord*
-GlobalActivityTracker::ModuleInfoRecord::CreateFrom(
-    const GlobalActivityTracker::ModuleInfo& info,
-    PersistentMemoryAllocator* allocator) {
-  Pickle pickler;
-  pickler.WriteString(info.file);
-  pickler.WriteString(info.debug_file);
-  size_t required_size = offsetof(ModuleInfoRecord, pickle) + pickler.size();
-  ModuleInfoRecord* record = allocator->New<ModuleInfoRecord>(required_size);
-  if (!record)
-    return nullptr;
-
-  // These fields never changes and are done before the record is made
-  // iterable so no thread protection is necessary.
-  record->size = info.size;
-  record->timestamp = info.timestamp;
-  record->age = info.age;
-  memcpy(record->identifier, info.identifier, sizeof(identifier));
-  memcpy(record->pickle, pickler.data(), pickler.size());
-  record->pickle_size = pickler.size();
-  record->changes.store(0, std::memory_order_relaxed);
-
-  // Initialize the owner info.
-  record->owner.Release_Initialize();
-
-  // Now set those fields that can change.
-  bool success = record->UpdateFrom(info);
-  DCHECK(success);
-  return record;
-}
-
-bool GlobalActivityTracker::ModuleInfoRecord::UpdateFrom(
-    const GlobalActivityTracker::ModuleInfo& info) {
-  // Updates can occur after the record is made visible so make changes atomic.
-  // A "strong" exchange ensures no false failures.
-  uint32_t old_changes = changes.load(std::memory_order_relaxed);
-  uint32_t new_changes = old_changes | kModuleInformationChanging;
-  if ((old_changes & kModuleInformationChanging) != 0 ||
-      !changes.compare_exchange_strong(old_changes, new_changes,
-                                       std::memory_order_acquire,
-                                       std::memory_order_acquire)) {
-    NOTREACHED() << "Multiple sources are updating module information.";
-    return false;
-  }
-
-  loaded = info.is_loaded ? 1 : 0;
-  address = info.address;
-  load_time = Time::Now().ToInternalValue();
-
-  bool success = changes.compare_exchange_strong(new_changes, old_changes + 1,
-                                                 std::memory_order_release,
-                                                 std::memory_order_relaxed);
-  DCHECK(success);
-  return true;
-}
-
-GlobalActivityTracker::ScopedThreadActivity::ScopedThreadActivity(
-    const void* program_counter,
-    const void* origin,
-    Activity::Type type,
-    const ActivityData& data,
-    bool lock_allowed)
-    : ThreadActivityTracker::ScopedActivity(GetOrCreateTracker(lock_allowed),
-                                            program_counter,
-                                            origin,
-                                            type,
-                                            data) {}
-
-GlobalActivityTracker::ScopedThreadActivity::~ScopedThreadActivity() {
-  if (tracker_ && tracker_->HasUserData(activity_id_)) {
-    GlobalActivityTracker* global = GlobalActivityTracker::Get();
-    AutoLock lock(global->user_data_allocator_lock_);
-    tracker_->ReleaseUserData(activity_id_, &global->user_data_allocator_);
-  }
-}
-
-ActivityUserData& GlobalActivityTracker::ScopedThreadActivity::user_data() {
-  if (!user_data_) {
-    if (tracker_) {
-      GlobalActivityTracker* global = GlobalActivityTracker::Get();
-      AutoLock lock(global->user_data_allocator_lock_);
-      user_data_ =
-          tracker_->GetUserData(activity_id_, &global->user_data_allocator_);
-    } else {
-      user_data_ = std::make_unique<ActivityUserData>();
-    }
-  }
-  return *user_data_;
-}
-
-GlobalActivityTracker::ThreadSafeUserData::ThreadSafeUserData(void* memory,
-                                                              size_t size,
-                                                              int64_t pid)
-    : ActivityUserData(memory, size, pid) {}
-
-GlobalActivityTracker::ThreadSafeUserData::~ThreadSafeUserData() = default;
-
-void GlobalActivityTracker::ThreadSafeUserData::Set(StringPiece name,
-                                                    ValueType type,
-                                                    const void* memory,
-                                                    size_t size) {
-  AutoLock lock(data_lock_);
-  ActivityUserData::Set(name, type, memory, size);
-}
-
-GlobalActivityTracker::ManagedActivityTracker::ManagedActivityTracker(
-    PersistentMemoryAllocator::Reference mem_reference,
-    void* base,
-    size_t size)
-    : ThreadActivityTracker(base, size),
-      mem_reference_(mem_reference),
-      mem_base_(base) {}
-
-GlobalActivityTracker::ManagedActivityTracker::~ManagedActivityTracker() {
-  // The global |g_tracker_| must point to the owner of this class since all
-  // objects of this type must be destructed before |g_tracker_| can be changed
-  // (something that only occurs in tests).
-  DCHECK(g_tracker_);
-  GlobalActivityTracker::Get()->ReturnTrackerMemory(this);
-}
-
-void GlobalActivityTracker::CreateWithAllocator(
-    std::unique_ptr<PersistentMemoryAllocator> allocator,
-    int stack_depth,
-    int64_t process_id) {
-  // There's no need to do anything with the result. It is self-managing.
-  GlobalActivityTracker* global_tracker =
-      new GlobalActivityTracker(std::move(allocator), stack_depth, process_id);
-  // Create a tracker for this thread since it is known.
-  global_tracker->CreateTrackerForCurrentThread();
-}
-
-#if !defined(OS_NACL)
-// static
-bool GlobalActivityTracker::CreateWithFile(const FilePath& file_path,
-                                           size_t size,
-                                           uint64_t id,
-                                           StringPiece name,
-                                           int stack_depth) {
-  DCHECK(!file_path.empty());
-  DCHECK_GE(static_cast<uint64_t>(std::numeric_limits<int64_t>::max()), size);
-
-  // Create and map the file into memory and make it globally available.
-  std::unique_ptr<MemoryMappedFile> mapped_file(new MemoryMappedFile());
-  bool success = mapped_file->Initialize(
-      File(file_path, File::FLAG_CREATE_ALWAYS | File::FLAG_READ |
-                          File::FLAG_WRITE | File::FLAG_SHARE_DELETE),
-      {0, size}, MemoryMappedFile::READ_WRITE_EXTEND);
-  if (!success)
-    return false;
-  if (!FilePersistentMemoryAllocator::IsFileAcceptable(*mapped_file, false))
-    return false;
-  CreateWithAllocator(std::make_unique<FilePersistentMemoryAllocator>(
-                          std::move(mapped_file), size, id, name, false),
-                      stack_depth, 0);
-  return true;
-}
-#endif  // !defined(OS_NACL)
-
-// static
-bool GlobalActivityTracker::CreateWithLocalMemory(size_t size,
-                                                  uint64_t id,
-                                                  StringPiece name,
-                                                  int stack_depth,
-                                                  int64_t process_id) {
-  CreateWithAllocator(
-      std::make_unique<LocalPersistentMemoryAllocator>(size, id, name),
-      stack_depth, process_id);
-  return true;
-}
-
-// static
-bool GlobalActivityTracker::CreateWithSharedMemory(
-    std::unique_ptr<SharedMemory> shm,
-    uint64_t id,
-    StringPiece name,
-    int stack_depth) {
-  if (shm->mapped_size() == 0 ||
-      !SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(*shm)) {
-    return false;
-  }
-  CreateWithAllocator(std::make_unique<SharedPersistentMemoryAllocator>(
-                          std::move(shm), id, name, false),
-                      stack_depth, 0);
-  return true;
-}
-
-// static
-bool GlobalActivityTracker::CreateWithSharedMemoryHandle(
-    const SharedMemoryHandle& handle,
-    size_t size,
-    uint64_t id,
-    StringPiece name,
-    int stack_depth) {
-  std::unique_ptr<SharedMemory> shm(
-      new SharedMemory(handle, /*readonly=*/false));
-  if (!shm->Map(size))
-    return false;
-  return CreateWithSharedMemory(std::move(shm), id, name, stack_depth);
-}
-
-// static
-void GlobalActivityTracker::SetForTesting(
-    std::unique_ptr<GlobalActivityTracker> tracker) {
-  CHECK(!subtle::NoBarrier_Load(&g_tracker_));
-  subtle::Release_Store(&g_tracker_,
-                        reinterpret_cast<uintptr_t>(tracker.release()));
-}
-
-// static
-std::unique_ptr<GlobalActivityTracker>
-GlobalActivityTracker::ReleaseForTesting() {
-  GlobalActivityTracker* tracker = Get();
-  if (!tracker)
-    return nullptr;
-
-  // Thread trackers assume that the global tracker is present for some
-  // operations so ensure that there aren't any.
-  tracker->ReleaseTrackerForCurrentThreadForTesting();
-  DCHECK_EQ(0, tracker->thread_tracker_count_.load(std::memory_order_relaxed));
-
-  subtle::Release_Store(&g_tracker_, 0);
-  return WrapUnique(tracker);
-}
-
-ThreadActivityTracker* GlobalActivityTracker::CreateTrackerForCurrentThread() {
-  DCHECK(!this_thread_tracker_.Get());
-
-  PersistentMemoryAllocator::Reference mem_reference;
-
-  {
-    base::AutoLock autolock(thread_tracker_allocator_lock_);
-    mem_reference = thread_tracker_allocator_.GetObjectReference();
-  }
-
-  if (!mem_reference) {
-    // Failure. This shouldn't happen. But be graceful if it does, probably
-    // because the underlying allocator wasn't given enough memory to satisfy
-    // to all possible requests.
-    NOTREACHED();
-    // Report the thread-count at which the allocator was full so that the
-    // failure can be seen and underlying memory resized appropriately.
-    UMA_HISTOGRAM_COUNTS_1000(
-        "ActivityTracker.ThreadTrackers.MemLimitTrackerCount",
-        thread_tracker_count_.load(std::memory_order_relaxed));
-    // Return null, just as if tracking wasn't enabled.
-    return nullptr;
-  }
-
-  // Convert the memory block found above into an actual memory address.
-  // Doing the conversion as a Header object enacts the 32/64-bit size
-  // consistency checks which would not otherwise be done. Unfortunately,
-  // some older compilers and MSVC don't have standard-conforming definitions
-  // of std::atomic which cause it not to be plain-old-data. Don't check on
-  // those platforms assuming that the checks on other platforms will be
-  // sufficient.
-  // TODO(bcwhite): Review this after major compiler releases.
-  DCHECK(mem_reference);
-  void* mem_base;
-  mem_base =
-      allocator_->GetAsObject<ThreadActivityTracker::Header>(mem_reference);
-
-  DCHECK(mem_base);
-  DCHECK_LE(stack_memory_size_, allocator_->GetAllocSize(mem_reference));
-
-  // Create a tracker with the acquired memory and set it as the tracker
-  // for this particular thread in thread-local-storage.
-  ManagedActivityTracker* tracker =
-      new ManagedActivityTracker(mem_reference, mem_base, stack_memory_size_);
-  DCHECK(tracker->IsValid());
-  this_thread_tracker_.Set(tracker);
-  int old_count = thread_tracker_count_.fetch_add(1, std::memory_order_relaxed);
-
-  UMA_HISTOGRAM_EXACT_LINEAR("ActivityTracker.ThreadTrackers.Count",
-                             old_count + 1, static_cast<int>(kMaxThreadCount));
-  return tracker;
-}
-
-void GlobalActivityTracker::ReleaseTrackerForCurrentThreadForTesting() {
-  ThreadActivityTracker* tracker =
-      reinterpret_cast<ThreadActivityTracker*>(this_thread_tracker_.Get());
-  if (tracker) {
-    this_thread_tracker_.Set(nullptr);
-    delete tracker;
-  }
-}
-
-void GlobalActivityTracker::SetBackgroundTaskRunner(
-    const scoped_refptr<TaskRunner>& runner) {
-  AutoLock lock(global_tracker_lock_);
-  background_task_runner_ = runner;
-}
-
-void GlobalActivityTracker::SetProcessExitCallback(
-    ProcessExitCallback callback) {
-  AutoLock lock(global_tracker_lock_);
-  process_exit_callback_ = callback;
-}
-
-void GlobalActivityTracker::RecordProcessLaunch(
-    ProcessId process_id,
-    const FilePath::StringType& cmd) {
-  const int64_t pid = process_id;
-  DCHECK_NE(GetProcessId(), pid);
-  DCHECK_NE(0, pid);
-
-  base::AutoLock lock(global_tracker_lock_);
-  if (base::ContainsKey(known_processes_, pid)) {
-    // TODO(bcwhite): Measure this in UMA.
-    NOTREACHED() << "Process #" << process_id
-                 << " was previously recorded as \"launched\""
-                 << " with no corresponding exit.\n"
-                 << known_processes_[pid];
-    known_processes_.erase(pid);
-  }
-
-#if defined(OS_WIN)
-  known_processes_.insert(std::make_pair(pid, UTF16ToUTF8(cmd)));
-#else
-  known_processes_.insert(std::make_pair(pid, cmd));
-#endif
-}
-
-void GlobalActivityTracker::RecordProcessLaunch(
-    ProcessId process_id,
-    const FilePath::StringType& exe,
-    const FilePath::StringType& args) {
-  if (exe.find(FILE_PATH_LITERAL(" "))) {
-    RecordProcessLaunch(process_id,
-                        FilePath::StringType(FILE_PATH_LITERAL("\"")) + exe +
-                            FILE_PATH_LITERAL("\" ") + args);
-  } else {
-    RecordProcessLaunch(process_id, exe + FILE_PATH_LITERAL(' ') + args);
-  }
-}
-
-void GlobalActivityTracker::RecordProcessExit(ProcessId process_id,
-                                              int exit_code) {
-  const int64_t pid = process_id;
-  DCHECK_NE(GetProcessId(), pid);
-  DCHECK_NE(0, pid);
-
-  scoped_refptr<TaskRunner> task_runner;
-  std::string command_line;
-  {
-    base::AutoLock lock(global_tracker_lock_);
-    task_runner = background_task_runner_;
-    auto found = known_processes_.find(pid);
-    if (found != known_processes_.end()) {
-      command_line = std::move(found->second);
-      known_processes_.erase(found);
-    } else {
-      DLOG(ERROR) << "Recording exit of unknown process #" << process_id;
-    }
-  }
-
-  // Use the current time to differentiate the process that just exited
-  // from any that might be created in the future with the same ID.
-  int64_t now_stamp = Time::Now().ToInternalValue();
-
-  // The persistent allocator is thread-safe so run the iteration and
-  // adjustments on a worker thread if one was provided.
-  if (task_runner && !task_runner->RunsTasksInCurrentSequence()) {
-    task_runner->PostTask(
-        FROM_HERE,
-        BindOnce(&GlobalActivityTracker::CleanupAfterProcess, Unretained(this),
-                 pid, now_stamp, exit_code, std::move(command_line)));
-    return;
-  }
-
-  CleanupAfterProcess(pid, now_stamp, exit_code, std::move(command_line));
-}
-
-void GlobalActivityTracker::SetProcessPhase(ProcessPhase phase) {
-  process_data().SetInt(kProcessPhaseDataKey, phase);
-}
-
-void GlobalActivityTracker::CleanupAfterProcess(int64_t process_id,
-                                                int64_t exit_stamp,
-                                                int exit_code,
-                                                std::string&& command_line) {
-  // The process may not have exited cleanly so its necessary to go through
-  // all the data structures it may have allocated in the persistent memory
-  // segment and mark them as "released". This will allow them to be reused
-  // later on.
-
-  PersistentMemoryAllocator::Iterator iter(allocator_.get());
-  PersistentMemoryAllocator::Reference ref;
-
-  ProcessExitCallback process_exit_callback;
-  {
-    AutoLock lock(global_tracker_lock_);
-    process_exit_callback = process_exit_callback_;
-  }
-  if (process_exit_callback) {
-    // Find the processes user-data record so the process phase can be passed
-    // to the callback.
-    ActivityUserData::Snapshot process_data_snapshot;
-    while ((ref = iter.GetNextOfType(kTypeIdProcessDataRecord)) != 0) {
-      const void* memory = allocator_->GetAsArray<char>(
-          ref, kTypeIdProcessDataRecord, PersistentMemoryAllocator::kSizeAny);
-      if (!memory)
-        continue;
-      int64_t found_id;
-      int64_t create_stamp;
-      if (ActivityUserData::GetOwningProcessId(memory, &found_id,
-                                               &create_stamp)) {
-        if (found_id == process_id && create_stamp < exit_stamp) {
-          const ActivityUserData process_data(const_cast<void*>(memory),
-                                              allocator_->GetAllocSize(ref));
-          process_data.CreateSnapshot(&process_data_snapshot);
-          break;  // No need to look for any others.
-        }
-      }
-    }
-    iter.Reset();  // So it starts anew when used below.
-
-    // Record the process's phase at exit so callback doesn't need to go
-    // searching based on a private key value.
-    ProcessPhase exit_phase = PROCESS_PHASE_UNKNOWN;
-    auto phase = process_data_snapshot.find(kProcessPhaseDataKey);
-    if (phase != process_data_snapshot.end())
-      exit_phase = static_cast<ProcessPhase>(phase->second.GetInt());
-
-    // Perform the callback.
-    process_exit_callback.Run(process_id, exit_stamp, exit_code, exit_phase,
-                              std::move(command_line),
-                              std::move(process_data_snapshot));
-  }
-
-  // Find all allocations associated with the exited process and free them.
-  uint32_t type;
-  while ((ref = iter.GetNext(&type)) != 0) {
-    switch (type) {
-      case kTypeIdActivityTracker:
-      case kTypeIdUserDataRecord:
-      case kTypeIdProcessDataRecord:
-      case ModuleInfoRecord::kPersistentTypeId: {
-        const void* memory = allocator_->GetAsArray<char>(
-            ref, type, PersistentMemoryAllocator::kSizeAny);
-        if (!memory)
-          continue;
-        int64_t found_id;
-        int64_t create_stamp;
-
-        // By convention, the OwningProcess structure is always the first
-        // field of the structure so there's no need to handle all the
-        // cases separately.
-        if (OwningProcess::GetOwningProcessId(memory, &found_id,
-                                              &create_stamp)) {
-          // Only change the type to be "free" if the process ID matches and
-          // the creation time is before the exit time (so PID re-use doesn't
-          // cause the erasure of something that is in-use). Memory is cleared
-          // here, rather than when it's needed, so as to limit the impact at
-          // that critical time.
-          if (found_id == process_id && create_stamp < exit_stamp)
-            allocator_->ChangeType(ref, ~type, type, /*clear=*/true);
-        }
-      } break;
-    }
-  }
-}
-
-void GlobalActivityTracker::RecordLogMessage(StringPiece message) {
-  // Allocate at least one extra byte so the string is NUL terminated. All
-  // memory returned by the allocator is guaranteed to be zeroed.
-  PersistentMemoryAllocator::Reference ref =
-      allocator_->Allocate(message.size() + 1, kTypeIdGlobalLogMessage);
-  char* memory = allocator_->GetAsArray<char>(ref, kTypeIdGlobalLogMessage,
-                                              message.size() + 1);
-  if (memory) {
-    memcpy(memory, message.data(), message.size());
-    allocator_->MakeIterable(ref);
-  }
-}
-
-void GlobalActivityTracker::RecordModuleInfo(const ModuleInfo& info) {
-  AutoLock lock(modules_lock_);
-  auto found = modules_.find(info.file);
-  if (found != modules_.end()) {
-    ModuleInfoRecord* record = found->second;
-    DCHECK(record);
-
-    // Update the basic state of module information that has been already
-    // recorded. It is assumed that the string information (identifier,
-    // version, etc.) remain unchanged which means that there's no need
-    // to create a new record to accommodate a possibly longer length.
-    record->UpdateFrom(info);
-    return;
-  }
-
-  ModuleInfoRecord* record =
-      ModuleInfoRecord::CreateFrom(info, allocator_.get());
-  if (!record)
-    return;
-  allocator_->MakeIterable(record);
-  modules_.emplace(info.file, record);
-}
-
-void GlobalActivityTracker::RecordFieldTrial(const std::string& trial_name,
-                                             StringPiece group_name) {
-  const std::string key = std::string("FieldTrial.") + trial_name;
-  process_data_.SetString(key, group_name);
-}
-
-void GlobalActivityTracker::RecordException(const void* pc,
-                                            const void* origin,
-                                            uint32_t code) {
-  RecordExceptionImpl(pc, origin, code);
-}
-
-void GlobalActivityTracker::MarkDeleted() {
-  allocator_->SetMemoryState(PersistentMemoryAllocator::MEMORY_DELETED);
-}
-
-GlobalActivityTracker::GlobalActivityTracker(
-    std::unique_ptr<PersistentMemoryAllocator> allocator,
-    int stack_depth,
-    int64_t process_id)
-    : allocator_(std::move(allocator)),
-      stack_memory_size_(ThreadActivityTracker::SizeForStackDepth(stack_depth)),
-      process_id_(process_id == 0 ? GetCurrentProcId() : process_id),
-      this_thread_tracker_(&OnTLSDestroy),
-      thread_tracker_count_(0),
-      thread_tracker_allocator_(allocator_.get(),
-                                kTypeIdActivityTracker,
-                                kTypeIdActivityTrackerFree,
-                                stack_memory_size_,
-                                kCachedThreadMemories,
-                                /*make_iterable=*/true),
-      user_data_allocator_(allocator_.get(),
-                           kTypeIdUserDataRecord,
-                           kTypeIdUserDataRecordFree,
-                           kUserDataSize,
-                           kCachedUserDataMemories,
-                           /*make_iterable=*/true),
-      process_data_(allocator_->GetAsArray<char>(
-                        AllocateFrom(allocator_.get(),
-                                     kTypeIdProcessDataRecordFree,
-                                     kProcessDataSize,
-                                     kTypeIdProcessDataRecord),
-                        kTypeIdProcessDataRecord,
-                        kProcessDataSize),
-                    kProcessDataSize,
-                    process_id_) {
-  DCHECK_NE(0, process_id_);
-
-  // Ensure that there is no other global object and then make this one such.
-  DCHECK(!g_tracker_);
-  subtle::Release_Store(&g_tracker_, reinterpret_cast<uintptr_t>(this));
-
-  // The data records must be iterable in order to be found by an analyzer.
-  allocator_->MakeIterable(allocator_->GetAsReference(
-      process_data_.GetBaseAddress(), kTypeIdProcessDataRecord));
-
-  // Note that this process has launched.
-  SetProcessPhase(PROCESS_LAUNCHED);
-
-  // Fetch and record all activated field trials.
-  FieldTrial::ActiveGroups active_groups;
-  FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
-  for (auto& group : active_groups)
-    RecordFieldTrial(group.trial_name, group.group_name);
-}
-
-GlobalActivityTracker::~GlobalActivityTracker() {
-  DCHECK(Get() == nullptr || Get() == this);
-  DCHECK_EQ(0, thread_tracker_count_.load(std::memory_order_relaxed));
-  subtle::Release_Store(&g_tracker_, 0);
-}
-
-void GlobalActivityTracker::ReturnTrackerMemory(
-    ManagedActivityTracker* tracker) {
-  PersistentMemoryAllocator::Reference mem_reference = tracker->mem_reference_;
-  void* mem_base = tracker->mem_base_;
-  DCHECK(mem_reference);
-  DCHECK(mem_base);
-
-  // Remove the destructed tracker from the set of known ones.
-  DCHECK_LE(1, thread_tracker_count_.load(std::memory_order_relaxed));
-  thread_tracker_count_.fetch_sub(1, std::memory_order_relaxed);
-
-  // Release this memory for re-use at a later time.
-  base::AutoLock autolock(thread_tracker_allocator_lock_);
-  thread_tracker_allocator_.ReleaseObjectReference(mem_reference);
-}
-
-void GlobalActivityTracker::RecordExceptionImpl(const void* pc,
-                                                const void* origin,
-                                                uint32_t code) {
-  // Get an existing tracker for this thread. It's not possible to create
-  // one at this point because such would involve memory allocations and
-  // other potentially complex operations that can cause failures if done
-  // within an exception handler. In most cases various operations will
-  // have already created the tracker so this shouldn't generally be a
-  // problem.
-  ThreadActivityTracker* tracker = GetTrackerForCurrentThread();
-  if (!tracker)
-    return;
-
-  tracker->RecordExceptionActivity(pc, origin, Activity::ACT_EXCEPTION,
-                                   ActivityData::ForException(code));
-}
-
-// static
-void GlobalActivityTracker::OnTLSDestroy(void* value) {
-  delete reinterpret_cast<ManagedActivityTracker*>(value);
-}
-
-ScopedActivity::ScopedActivity(const void* program_counter,
-                               uint8_t action,
-                               uint32_t id,
-                               int32_t info)
-    : GlobalActivityTracker::ScopedThreadActivity(
-          program_counter,
-          nullptr,
-          static_cast<Activity::Type>(Activity::ACT_GENERIC | action),
-          ActivityData::ForGeneric(id, info),
-          /*lock_allowed=*/true),
-      id_(id) {
-  // The action must not affect the category bits of the activity type.
-  DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK);
-}
-
-void ScopedActivity::ChangeAction(uint8_t action) {
-  DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK);
-  ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action),
-                    kNullActivityData);
-}
-
-void ScopedActivity::ChangeInfo(int32_t info) {
-  ChangeTypeAndData(Activity::ACT_NULL, ActivityData::ForGeneric(id_, info));
-}
-
-void ScopedActivity::ChangeActionAndInfo(uint8_t action, int32_t info) {
-  DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK);
-  ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action),
-                    ActivityData::ForGeneric(id_, info));
-}
-
-ScopedTaskRunActivity::ScopedTaskRunActivity(
-    const void* program_counter,
-    const base::PendingTask& task)
-    : GlobalActivityTracker::ScopedThreadActivity(
-          program_counter,
-          task.posted_from.program_counter(),
-          Activity::ACT_TASK_RUN,
-          ActivityData::ForTask(task.sequence_num),
-          /*lock_allowed=*/true) {}
-
-ScopedLockAcquireActivity::ScopedLockAcquireActivity(
-    const void* program_counter,
-    const base::internal::LockImpl* lock)
-    : GlobalActivityTracker::ScopedThreadActivity(
-          program_counter,
-          nullptr,
-          Activity::ACT_LOCK_ACQUIRE,
-          ActivityData::ForLock(lock),
-          /*lock_allowed=*/false) {}
-
-ScopedEventWaitActivity::ScopedEventWaitActivity(
-    const void* program_counter,
-    const base::WaitableEvent* event)
-    : GlobalActivityTracker::ScopedThreadActivity(
-          program_counter,
-          nullptr,
-          Activity::ACT_EVENT_WAIT,
-          ActivityData::ForEvent(event),
-          /*lock_allowed=*/true) {}
-
-ScopedThreadJoinActivity::ScopedThreadJoinActivity(
-    const void* program_counter,
-    const base::PlatformThreadHandle* thread)
-    : GlobalActivityTracker::ScopedThreadActivity(
-          program_counter,
-          nullptr,
-          Activity::ACT_THREAD_JOIN,
-          ActivityData::ForThread(*thread),
-          /*lock_allowed=*/true) {}
-
-#if !defined(OS_NACL) && !defined(OS_IOS)
-ScopedProcessWaitActivity::ScopedProcessWaitActivity(
-    const void* program_counter,
-    const base::Process* process)
-    : GlobalActivityTracker::ScopedThreadActivity(
-          program_counter,
-          nullptr,
-          Activity::ACT_PROCESS_WAIT,
-          ActivityData::ForProcess(process->Pid()),
-          /*lock_allowed=*/true) {}
-#endif
-
-}  // namespace debug
-}  // namespace base
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h
deleted file mode 100644
index bfd9f9d..0000000
--- a/base/debug/activity_tracker.h
+++ /dev/null
@@ -1,1360 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Activity tracking provides a low-overhead method of collecting information
-// about the state of the application for analysis both while it is running
-// and after it has terminated unexpectedly. Its primary purpose is to help
-// locate reasons the browser becomes unresponsive by providing insight into
-// what all the various threads and processes are (or were) doing.
-
-#ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_
-#define BASE_DEBUG_ACTIVITY_TRACKER_H_
-
-// std::atomic is undesired due to performance issues when used as global
-// variables. There are no such instances here. This module uses the
-// PersistentMemoryAllocator which also uses std::atomic and is written
-// by the same author.
-#include <atomic>
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/atomicops.h"
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
-#include "base/location.h"
-#include "base/memory/shared_memory.h"
-#include "base/metrics/persistent_memory_allocator.h"
-#include "base/process/process_handle.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/task_runner.h"
-#include "base/threading/platform_thread.h"
-#include "base/threading/thread_local_storage.h"
-
-namespace base {
-
-struct PendingTask;
-
-class FilePath;
-class Lock;
-class PlatformThreadHandle;
-class Process;
-class WaitableEvent;
-
-namespace debug {
-
-class ThreadActivityTracker;
-
-
-enum : int {
-  // The maximum number of call-stack addresses stored per activity. This
-  // cannot be changed without also changing the version number of the
-  // structure. See kTypeIdActivityTracker in GlobalActivityTracker.
-  kActivityCallStackSize = 10,
-};
-
-// A class for keeping all information needed to verify that a structure is
-// associated with a given process.
-struct OwningProcess {
-  OwningProcess();
-  ~OwningProcess();
-
-  // Initializes structure with the current process id and the current time.
-  // These can uniquely identify a process. A unique non-zero data_id will be
-  // set making it possible to tell using atomic reads if the data has changed.
-  void Release_Initialize(int64_t pid = 0);
-
-  // Explicitly sets the process ID.
-  void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp);
-
-  // Gets the associated process ID, in native form, and the creation timestamp
-  // from memory without loading the entire structure for analysis. This will
-  // return false if no valid process ID is available.
-  static bool GetOwningProcessId(const void* memory,
-                                 int64_t* out_id,
-                                 int64_t* out_stamp);
-
-  // SHA1(base::debug::OwningProcess): Increment this if structure changes!
-  static constexpr uint32_t kPersistentTypeId = 0xB1179672 + 1;
-
-  // Expected size for 32/64-bit check by PersistentMemoryAllocator.
-  static constexpr size_t kExpectedInstanceSize = 24;
-
-  std::atomic<uint32_t> data_id;
-  uint32_t padding;
-  int64_t process_id;
-  int64_t create_stamp;
-};
-
-// The data associated with an activity is dependent upon the activity type.
-// This union defines all of the various fields. All fields must be explicitly
-// sized types to ensure no interoperability problems between 32-bit and
-// 64-bit systems.
-union ActivityData {
-  // Expected size for 32/64-bit check.
-  // TODO(bcwhite): VC2015 doesn't allow statics in unions. Fix when it does.
-  // static constexpr size_t kExpectedInstanceSize = 8;
-
-  // Generic activities don't have any defined structure.
-  struct {
-    uint32_t id;   // An arbitrary identifier used for association.
-    int32_t info;  // An arbitrary value used for information purposes.
-  } generic;
-  struct {
-    uint64_t sequence_id;  // The sequence identifier of the posted task.
-  } task;
-  struct {
-    uint64_t lock_address;  // The memory address of the lock object.
-  } lock;
-  struct {
-    uint64_t event_address;  // The memory address of the event object.
-  } event;
-  struct {
-    int64_t thread_id;  // A unique identifier for a thread within a process.
-  } thread;
-  struct {
-    int64_t process_id;  // A unique identifier for a process.
-  } process;
-  struct {
-    uint32_t code;  // An "exception code" number.
-  } exception;
-
-  // These methods create an ActivityData object from the appropriate
-  // parameters. Objects of this type should always be created this way to
-  // ensure that no fields remain unpopulated should the set of recorded
-  // fields change. They're defined inline where practical because they
-  // reduce to loading a small local structure with a few values, roughly
-  // the same as loading all those values into parameters.
-
-  static ActivityData ForGeneric(uint32_t id, int32_t info) {
-    ActivityData data;
-    data.generic.id = id;
-    data.generic.info = info;
-    return data;
-  }
-
-  static ActivityData ForTask(uint64_t sequence) {
-    ActivityData data;
-    data.task.sequence_id = sequence;
-    return data;
-  }
-
-  static ActivityData ForLock(const void* lock) {
-    ActivityData data;
-    data.lock.lock_address = reinterpret_cast<uintptr_t>(lock);
-    return data;
-  }
-
-  static ActivityData ForEvent(const void* event) {
-    ActivityData data;
-    data.event.event_address = reinterpret_cast<uintptr_t>(event);
-    return data;
-  }
-
-  static ActivityData ForThread(const PlatformThreadHandle& handle);
-  static ActivityData ForThread(const int64_t id) {
-    ActivityData data;
-    data.thread.thread_id = id;
-    return data;
-  }
-
-  static ActivityData ForProcess(const int64_t id) {
-    ActivityData data;
-    data.process.process_id = id;
-    return data;
-  }
-
-  static ActivityData ForException(const uint32_t code) {
-    ActivityData data;
-    data.exception.code = code;
-    return data;
-  }
-};
-
-// A "null" activity-data that can be passed to indicate "do not change".
-extern const ActivityData kNullActivityData;
-
-
-// A helper class that is used for managing memory allocations within a
-// persistent memory allocator. Instances of this class are NOT thread-safe.
-// Use from a single thread or protect access with a lock.
-class BASE_EXPORT ActivityTrackerMemoryAllocator {
- public:
-  using Reference = PersistentMemoryAllocator::Reference;
-
-  // Creates a instance for allocating objects of a fixed |object_type|, a
-  // corresponding |object_free| type, and the |object_size|. An internal
-  // cache of the last |cache_size| released references will be kept for
-  // quick future fetches. If |make_iterable| then allocated objects will
-  // be marked "iterable" in the allocator.
-  ActivityTrackerMemoryAllocator(PersistentMemoryAllocator* allocator,
-                                 uint32_t object_type,
-                                 uint32_t object_free_type,
-                                 size_t object_size,
-                                 size_t cache_size,
-                                 bool make_iterable);
-  ~ActivityTrackerMemoryAllocator();
-
-  // Gets a reference to an object of the configured type. This can return
-  // a null reference if it was not possible to allocate the memory.
-  Reference GetObjectReference();
-
-  // Returns an object to the "free" pool.
-  void ReleaseObjectReference(Reference ref);
-
-  // Helper function to access an object allocated using this instance.
-  template <typename T>
-  T* GetAsObject(Reference ref) {
-    return allocator_->GetAsObject<T>(ref);
-  }
-
-  // Similar to GetAsObject() but converts references to arrays of objects.
-  template <typename T>
-  T* GetAsArray(Reference ref, size_t count) {
-    return allocator_->GetAsArray<T>(ref, object_type_, count);
-  }
-
-  // The current "used size" of the internal cache, visible for testing.
-  size_t cache_used() const { return cache_used_; }
-
- private:
-  PersistentMemoryAllocator* const allocator_;
-  const uint32_t object_type_;
-  const uint32_t object_free_type_;
-  const size_t object_size_;
-  const size_t cache_size_;
-  const bool make_iterable_;
-
-  // An iterator for going through persistent memory looking for free'd objects.
-  PersistentMemoryAllocator::Iterator iterator_;
-
-  // The cache of released object memories.
-  std::unique_ptr<Reference[]> cache_values_;
-  size_t cache_used_;
-
-  DISALLOW_COPY_AND_ASSIGN(ActivityTrackerMemoryAllocator);
-};
-
-
-// This structure is the full contents recorded for every activity pushed
-// onto the stack. The |activity_type| indicates what is actually stored in
-// the |data| field. All fields must be explicitly sized types to ensure no
-// interoperability problems between 32-bit and 64-bit systems.
-struct Activity {
-  // SHA1(base::debug::Activity): Increment this if structure changes!
-  static constexpr uint32_t kPersistentTypeId = 0x99425159 + 1;
-  // Expected size for 32/64-bit check. Update this if structure changes!
-  static constexpr size_t kExpectedInstanceSize =
-      48 + 8 * kActivityCallStackSize;
-
-  // The type of an activity on the stack. Activities are broken into
-  // categories with the category ID taking the top 4 bits and the lower
-  // bits representing an action within that category. This combination
-  // makes it easy to "switch" based on the type during analysis.
-  enum Type : uint8_t {
-    // This "null" constant is used to indicate "do not change" in calls.
-    ACT_NULL = 0,
-
-    // Task activities involve callbacks posted to a thread or thread-pool
-    // using the PostTask() method or any of its friends.
-    ACT_TASK = 1 << 4,
-    ACT_TASK_RUN = ACT_TASK,
-
-    // Lock activities involve the acquisition of "mutex" locks.
-    ACT_LOCK = 2 << 4,
-    ACT_LOCK_ACQUIRE = ACT_LOCK,
-    ACT_LOCK_RELEASE,
-
-    // Event activities involve operations on a WaitableEvent.
-    ACT_EVENT = 3 << 4,
-    ACT_EVENT_WAIT = ACT_EVENT,
-    ACT_EVENT_SIGNAL,
-
-    // Thread activities involve the life management of threads.
-    ACT_THREAD = 4 << 4,
-    ACT_THREAD_START = ACT_THREAD,
-    ACT_THREAD_JOIN,
-
-    // Process activities involve the life management of processes.
-    ACT_PROCESS = 5 << 4,
-    ACT_PROCESS_START = ACT_PROCESS,
-    ACT_PROCESS_WAIT,
-
-    // Exception activities indicate the occurence of something unexpected.
-    ACT_EXCEPTION = 14 << 4,
-
-    // Generic activities are user defined and can be anything.
-    ACT_GENERIC = 15 << 4,
-
-    // These constants can be used to separate the category and action from
-    // a combined activity type.
-    ACT_CATEGORY_MASK = 0xF << 4,
-    ACT_ACTION_MASK = 0xF
-  };
-
-  // Internal representation of time. During collection, this is in "ticks"
-  // but when returned in a snapshot, it is "wall time".
-  int64_t time_internal;
-
-  // The address that pushed the activity onto the stack as a raw number.
-  uint64_t calling_address;
-
-  // The address that is the origin of the activity if it not obvious from
-  // the call stack. This is useful for things like tasks that are posted
-  // from a completely different thread though most activities will leave
-  // it null.
-  uint64_t origin_address;
-
-  // Array of program-counters that make up the top of the call stack.
-  // Despite the fixed size, this list is always null-terminated. Entries
-  // after the terminator have no meaning and may or may not also be null.
-  // The list will be completely empty if call-stack collection is not
-  // enabled.
-  uint64_t call_stack[kActivityCallStackSize];
-
-  // Reference to arbitrary user data within the persistent memory segment
-  // and a unique identifier for it.
-  uint32_t user_data_ref;
-  uint32_t user_data_id;
-
-  // The (enumerated) type of the activity. This defines what fields of the
-  // |data| record are valid.
-  uint8_t activity_type;
-
-  // Padding to ensure that the next member begins on a 64-bit boundary
-  // even on 32-bit builds which ensures inter-operability between CPU
-  // architectures. New fields can be taken from this space.
-  uint8_t padding[7];
-
-  // Information specific to the |activity_type|.
-  ActivityData data;
-
-  static void FillFrom(Activity* activity,
-                       const void* program_counter,
-                       const void* origin,
-                       Type type,
-                       const ActivityData& data);
-};
-
-// This class manages arbitrary user data that can be associated with activities
-// done by a thread by supporting key/value pairs of any type. This can provide
-// additional information during debugging. It is also used to store arbitrary
-// global data. All updates must be done from the same thread though other
-// threads can read it concurrently if they create new objects using the same
-// memory.
-class BASE_EXPORT ActivityUserData {
- public:
-  // List of known value type. REFERENCE types must immediately follow the non-
-  // external types.
-  enum ValueType : uint8_t {
-    END_OF_VALUES = 0,
-    RAW_VALUE,
-    RAW_VALUE_REFERENCE,
-    STRING_VALUE,
-    STRING_VALUE_REFERENCE,
-    CHAR_VALUE,
-    BOOL_VALUE,
-    SIGNED_VALUE,
-    UNSIGNED_VALUE,
-  };
-
-  class BASE_EXPORT TypedValue {
-   public:
-    TypedValue();
-    TypedValue(const TypedValue& other);
-    ~TypedValue();
-
-    ValueType type() const { return type_; }
-
-    // These methods return the extracted value in the correct format.
-    StringPiece Get() const;
-    StringPiece GetString() const;
-    bool GetBool() const;
-    char GetChar() const;
-    int64_t GetInt() const;
-    uint64_t GetUint() const;
-
-    // These methods return references to process memory as originally provided
-    // to corresponding Set calls. USE WITH CAUTION! There is no guarantee that
-    // the referenced memory is assessible or useful.  It's possible that:
-    //  - the memory was free'd and reallocated for a different purpose
-    //  - the memory has been released back to the OS
-    //  - the memory belongs to a different process's address space
-    // Dereferencing the returned StringPiece when the memory is not accessible
-    // will cause the program to SEGV!
-    StringPiece GetReference() const;
-    StringPiece GetStringReference() const;
-
-   private:
-    friend class ActivityUserData;
-
-    ValueType type_ = END_OF_VALUES;
-    uint64_t short_value_;    // Used to hold copy of numbers, etc.
-    std::string long_value_;  // Used to hold copy of raw/string data.
-    StringPiece ref_value_;   // Used to hold reference to external data.
-  };
-
-  using Snapshot = std::map<std::string, TypedValue>;
-
-  // Initialize the object either as a "sink" that just accepts and discards
-  // data or an active one that writes to a given (zeroed) memory block.
-  ActivityUserData();
-  ActivityUserData(void* memory, size_t size, int64_t pid = 0);
-  virtual ~ActivityUserData();
-
-  // Gets the unique ID number for this user data. If this changes then the
-  // contents have been overwritten by another thread. The return value is
-  // always non-zero unless it's actually just a data "sink".
-  uint32_t id() const {
-    return header_ ? header_->owner.data_id.load(std::memory_order_relaxed) : 0;
-  }
-
-  // Writes a |value| (as part of a key/value pair) that will be included with
-  // the activity in any reports. The same |name| can be written multiple times
-  // with each successive call overwriting the previously stored |value|. For
-  // raw and string values, the maximum size of successive writes is limited by
-  // the first call. The length of "name" is limited to 255 characters.
-  //
-  // This information is stored on a "best effort" basis. It may be dropped if
-  // the memory buffer is full or the associated activity is beyond the maximum
-  // recording depth.
-  void Set(StringPiece name, const void* memory, size_t size) {
-    Set(name, RAW_VALUE, memory, size);
-  }
-  void SetString(StringPiece name, StringPiece value) {
-    Set(name, STRING_VALUE, value.data(), value.length());
-  }
-  void SetString(StringPiece name, StringPiece16 value) {
-    SetString(name, UTF16ToUTF8(value));
-  }
-  void SetBool(StringPiece name, bool value) {
-    char cvalue = value ? 1 : 0;
-    Set(name, BOOL_VALUE, &cvalue, sizeof(cvalue));
-  }
-  void SetChar(StringPiece name, char value) {
-    Set(name, CHAR_VALUE, &value, sizeof(value));
-  }
-  void SetInt(StringPiece name, int64_t value) {
-    Set(name, SIGNED_VALUE, &value, sizeof(value));
-  }
-  void SetUint(StringPiece name, uint64_t value) {
-    Set(name, UNSIGNED_VALUE, &value, sizeof(value));
-  }
-
-  // These function as above but don't actually copy the data into the
-  // persistent memory. They store unaltered pointers along with a size. These
-  // can be used in conjuction with a memory dump to find certain large pieces
-  // of information.
-  void SetReference(StringPiece name, const void* memory, size_t size) {
-    SetReference(name, RAW_VALUE_REFERENCE, memory, size);
-  }
-  void SetStringReference(StringPiece name, StringPiece value) {
-    SetReference(name, STRING_VALUE_REFERENCE, value.data(), value.length());
-  }
-
-  // Creates a snapshot of the key/value pairs contained within. The returned
-  // data will be fixed, independent of whatever changes afterward. There is
-  // some protection against concurrent modification. This will return false
-  // if the data is invalid or if a complete overwrite of the contents is
-  // detected.
-  bool CreateSnapshot(Snapshot* output_snapshot) const;
-
-  // Gets the base memory address used for storing data.
-  const void* GetBaseAddress() const;
-
-  // Explicitly sets the process ID.
-  void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp);
-
-  // Gets the associated process ID, in native form, and the creation timestamp
-  // from tracker memory without loading the entire structure for analysis. This
-  // will return false if no valid process ID is available.
-  static bool GetOwningProcessId(const void* memory,
-                                 int64_t* out_id,
-                                 int64_t* out_stamp);
-
- protected:
-  virtual void Set(StringPiece name,
-                   ValueType type,
-                   const void* memory,
-                   size_t size);
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest);
-
-  enum : size_t { kMemoryAlignment = sizeof(uint64_t) };
-
-  // A structure that defines the structure header in memory.
-  struct MemoryHeader {
-    MemoryHeader();
-    ~MemoryHeader();
-
-    OwningProcess owner;  // Information about the creating process.
-  };
-
-  // Header to a key/value record held in persistent memory.
-  struct FieldHeader {
-    FieldHeader();
-    ~FieldHeader();
-
-    std::atomic<uint8_t> type;         // Encoded ValueType
-    uint8_t name_size;                 // Length of "name" key.
-    std::atomic<uint16_t> value_size;  // Actual size of of the stored value.
-    uint16_t record_size;              // Total storage of name, value, header.
-  };
-
-  // A structure used to reference data held outside of persistent memory.
-  struct ReferenceRecord {
-    uint64_t address;
-    uint64_t size;
-  };
-
-  // This record is used to hold known value is a map so that they can be
-  // found and overwritten later.
-  struct ValueInfo {
-    ValueInfo();
-    ValueInfo(ValueInfo&&);
-    ~ValueInfo();
-
-    StringPiece name;                 // The "key" of the record.
-    ValueType type;                   // The type of the value.
-    void* memory;                     // Where the "value" is held.
-    std::atomic<uint16_t>* size_ptr;  // Address of the actual size of value.
-    size_t extent;                    // The total storage of the value,
-  };                                  // typically rounded up for alignment.
-
-  void SetReference(StringPiece name,
-                    ValueType type,
-                    const void* memory,
-                    size_t size);
-
-  // Loads any data already in the memory segment. This allows for accessing
-  // records created previously. If this detects that the underlying data has
-  // gone away (cleared by another thread/process), it will invalidate all the
-  // data in this object and turn it into simple "sink" with no values to
-  // return.
-  void ImportExistingData() const;
-
-  // A map of all the values within the memory block, keyed by name for quick
-  // updates of the values. This is "mutable" because it changes on "const"
-  // objects even when the actual data values can't change.
-  mutable std::map<StringPiece, ValueInfo> values_;
-
-  // Information about the memory block in which new data can be stored. These
-  // are "mutable" because they change even on "const" objects that are just
-  // skipping already set values.
-  mutable char* memory_;
-  mutable size_t available_;
-
-  // A pointer to the memory header for this instance.
-  MemoryHeader* const header_;
-
-  // These hold values used when initially creating the object. They are
-  // compared against current header values to check for outside changes.
-  const uint32_t orig_data_id;
-  const int64_t orig_process_id;
-  const int64_t orig_create_stamp;
-
-  DISALLOW_COPY_AND_ASSIGN(ActivityUserData);
-};
-
-// This class manages tracking a stack of activities for a single thread in
-// a persistent manner, implementing a bounded-size stack in a fixed-size
-// memory allocation. In order to support an operational mode where another
-// thread is analyzing this data in real-time, atomic operations are used
-// where necessary to guarantee a consistent view from the outside.
-//
-// This class is not generally used directly but instead managed by the
-// GlobalActivityTracker instance and updated using Scoped*Activity local
-// objects.
-class BASE_EXPORT ThreadActivityTracker {
- public:
-  using ActivityId = uint32_t;
-
-  // This structure contains all the common information about the thread so
-  // it doesn't have to be repeated in every entry on the stack. It is defined
-  // and used completely within the .cc file.
-  struct Header;
-
-  // This structure holds a copy of all the internal data at the moment the
-  // "snapshot" operation is done. It is disconnected from the live tracker
-  // so that continued operation of the thread will not cause changes here.
-  struct BASE_EXPORT Snapshot {
-    // Explicit constructor/destructor are needed because of complex types
-    // with non-trivial default constructors and destructors.
-    Snapshot();
-    ~Snapshot();
-
-    // The name of the thread as set when it was created. The name may be
-    // truncated due to internal length limitations.
-    std::string thread_name;
-
-    // The timestamp at which this process was created.
-    int64_t create_stamp;
-
-    // The process and thread IDs. These values have no meaning other than
-    // they uniquely identify a running process and a running thread within
-    // that process.  Thread-IDs can be re-used across different processes
-    // and both can be re-used after the process/thread exits.
-    int64_t process_id = 0;
-    int64_t thread_id = 0;
-
-    // The current stack of activities that are underway for this thread. It
-    // is limited in its maximum size with later entries being left off.
-    std::vector<Activity> activity_stack;
-
-    // The current total depth of the activity stack, including those later
-    // entries not recorded in the |activity_stack| vector.
-    uint32_t activity_stack_depth = 0;
-
-    // The last recorded "exception" activity.
-    Activity last_exception;
-  };
-
-  // This is the base class for having the compiler manage an activity on the
-  // tracker's stack. It does nothing but call methods on the passed |tracker|
-  // if it is not null, making it safe (and cheap) to create these objects
-  // even if activity tracking is not enabled.
-  class BASE_EXPORT ScopedActivity {
-   public:
-    ScopedActivity(ThreadActivityTracker* tracker,
-                   const void* program_counter,
-                   const void* origin,
-                   Activity::Type type,
-                   const ActivityData& data);
-    ~ScopedActivity();
-
-    // Changes some basic metadata about the activity.
-    void ChangeTypeAndData(Activity::Type type, const ActivityData& data);
-
-   protected:
-    // The thread tracker to which this object reports. It can be null if
-    // activity tracking is not (yet) enabled.
-    ThreadActivityTracker* const tracker_;
-
-    // An identifier that indicates a specific activity on the stack.
-    ActivityId activity_id_;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(ScopedActivity);
-  };
-
-  // A ThreadActivityTracker runs on top of memory that is managed externally.
-  // It must be large enough for the internal header and a few Activity
-  // blocks. See SizeForStackDepth().
-  ThreadActivityTracker(void* base, size_t size);
-  virtual ~ThreadActivityTracker();
-
-  // Indicates that an activity has started from a given |origin| address in
-  // the code, though it can be null if the creator's address is not known.
-  // The |type| and |data| describe the activity. |program_counter| should be
-  // the result of GetProgramCounter() where push is called. Returned is an
-  // ID that can be used to adjust the pushed activity.
-  ActivityId PushActivity(const void* program_counter,
-                          const void* origin,
-                          Activity::Type type,
-                          const ActivityData& data);
-
-  // An inlined version of the above that gets the program counter where it
-  // is called.
-  ALWAYS_INLINE
-  ActivityId PushActivity(const void* origin,
-                          Activity::Type type,
-                          const ActivityData& data) {
-    return PushActivity(GetProgramCounter(), origin, type, data);
-  }
-
-  // Changes the activity |type| and |data| of the top-most entry on the stack.
-  // This is useful if the information has changed and it is desireable to
-  // track that change without creating a new stack entry. If the type is
-  // ACT_NULL or the data is kNullActivityData then that value will remain
-  // unchanged. The type, if changed, must remain in the same category.
-  // Changing both is not atomic so a snapshot operation could occur between
-  // the update of |type| and |data| or between update of |data| fields.
-  void ChangeActivity(ActivityId id,
-                      Activity::Type type,
-                      const ActivityData& data);
-
-  // Indicates that an activity has completed.
-  void PopActivity(ActivityId id);
-
-  // Sets the user-data information for an activity.
-  std::unique_ptr<ActivityUserData> GetUserData(
-      ActivityId id,
-      ActivityTrackerMemoryAllocator* allocator);
-
-  // Returns if there is true use-data associated with a given ActivityId since
-  // it's possible than any returned object is just a sink.
-  bool HasUserData(ActivityId id);
-
-  // Release the user-data information for an activity.
-  void ReleaseUserData(ActivityId id,
-                       ActivityTrackerMemoryAllocator* allocator);
-
-  // Save an exception. |origin| is the location of the exception.
-  void RecordExceptionActivity(const void* program_counter,
-                               const void* origin,
-                               Activity::Type type,
-                               const ActivityData& data);
-
-  // Returns whether the current data is valid or not. It is not valid if
-  // corruption has been detected in the header or other data structures.
-  bool IsValid() const;
-
-  // Gets a copy of the tracker contents for analysis. Returns false if a
-  // snapshot was not possible, perhaps because the data is not valid; the
-  // contents of |output_snapshot| are undefined in that case. The current
-  // implementation does not support concurrent snapshot operations.
-  bool CreateSnapshot(Snapshot* output_snapshot) const;
-
-  // Gets the base memory address used for storing data.
-  const void* GetBaseAddress();
-
-  // Access the "data version" value so tests can determine if an activity
-  // was pushed and popped in a single call.
-  uint32_t GetDataVersionForTesting();
-
-  // Explicitly sets the process ID.
-  void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp);
-
-  // Gets the associated process ID, in native form, and the creation timestamp
-  // from tracker memory without loading the entire structure for analysis. This
-  // will return false if no valid process ID is available.
-  static bool GetOwningProcessId(const void* memory,
-                                 int64_t* out_id,
-                                 int64_t* out_stamp);
-
-  // Calculates the memory size required for a given stack depth, including
-  // the internal header structure for the stack.
-  static size_t SizeForStackDepth(int stack_depth);
-
- private:
-  friend class ActivityTrackerTest;
-
-  bool CalledOnValidThread();
-
-  std::unique_ptr<ActivityUserData> CreateUserDataForActivity(
-      Activity* activity,
-      ActivityTrackerMemoryAllocator* allocator);
-
-  Header* const header_;        // Pointer to the Header structure.
-  Activity* const stack_;       // The stack of activities.
-
-#if DCHECK_IS_ON()
-  // The ActivityTracker is thread bound, and will be invoked across all the
-  // sequences that run on the thread. A ThreadChecker does not work here, as it
-  // asserts on running in the same sequence each time.
-  const PlatformThreadRef thread_id_;  // The thread this instance is bound to.
-#endif
-  const uint32_t stack_slots_;  // The total number of stack slots.
-
-  bool valid_ = false;          // Tracks whether the data is valid or not.
-
-  DISALLOW_COPY_AND_ASSIGN(ThreadActivityTracker);
-};
-
-
-// The global tracker manages all the individual thread trackers. Memory for
-// the thread trackers is taken from a PersistentMemoryAllocator which allows
-// for the data to be analyzed by a parallel process or even post-mortem.
-class BASE_EXPORT GlobalActivityTracker {
- public:
-  // Type identifiers used when storing in persistent memory so they can be
-  // identified during extraction; the first 4 bytes of the SHA1 of the name
-  // is used as a unique integer. A "version number" is added to the base
-  // so that, if the structure of that object changes, stored older versions
-  // will be safely ignored. These are public so that an external process
-  // can recognize records of this type within an allocator.
-  enum : uint32_t {
-    kTypeIdActivityTracker = 0x5D7381AF + 4,   // SHA1(ActivityTracker) v4
-    kTypeIdUserDataRecord = 0x615EDDD7 + 3,    // SHA1(UserDataRecord) v3
-    kTypeIdGlobalLogMessage = 0x4CF434F9 + 1,  // SHA1(GlobalLogMessage) v1
-    kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100,
-
-    kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker,
-    kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord,
-    kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord,
-  };
-
-  // An enumeration of common process life stages. All entries are given an
-  // explicit number so they are known and remain constant; this allows for
-  // cross-version analysis either locally or on a server.
-  enum ProcessPhase : int {
-    // The phases are generic and may have meaning to the tracker.
-    PROCESS_PHASE_UNKNOWN = 0,
-    PROCESS_LAUNCHED = 1,
-    PROCESS_LAUNCH_FAILED = 2,
-    PROCESS_EXITED_CLEANLY = 10,
-    PROCESS_EXITED_WITH_CODE = 11,
-
-    // Add here whatever is useful for analysis.
-    PROCESS_SHUTDOWN_STARTED = 100,
-    PROCESS_MAIN_LOOP_STARTED = 101,
-  };
-
-  // A callback made when a process exits to allow immediate analysis of its
-  // data. Note that the system may reuse the |process_id| so when fetching
-  // records it's important to ensure that what is returned was created before
-  // the |exit_stamp|. Movement of |process_data| information is allowed.
-  using ProcessExitCallback =
-      Callback<void(int64_t process_id,
-                    int64_t exit_stamp,
-                    int exit_code,
-                    ProcessPhase exit_phase,
-                    std::string&& command_line,
-                    ActivityUserData::Snapshot&& process_data)>;
-
-  // This structure contains information about a loaded module, as shown to
-  // users of the tracker.
-  struct BASE_EXPORT ModuleInfo {
-    ModuleInfo();
-    ModuleInfo(ModuleInfo&& rhs);
-    ModuleInfo(const ModuleInfo& rhs);
-    ~ModuleInfo();
-
-    ModuleInfo& operator=(ModuleInfo&& rhs);
-    ModuleInfo& operator=(const ModuleInfo& rhs);
-
-    // Information about where and when the module was loaded/unloaded.
-    bool is_loaded = false;  // Was the last operation a load or unload?
-    uintptr_t address = 0;   // Address of the last load operation.
-    int64_t load_time = 0;   // Time of last change; set automatically.
-
-    // Information about the module itself. These never change no matter how
-    // many times a module may be loaded and unloaded.
-    size_t size = 0;         // The size of the loaded module.
-    uint32_t timestamp = 0;  // Opaque "timestamp" for the module.
-    uint32_t age = 0;        // Opaque "age" for the module.
-    uint8_t identifier[16];  // Opaque identifier (GUID, etc.) for the module.
-    std::string file;        // The full path to the file. (UTF-8)
-    std::string debug_file;  // The full path to the debug file.
-  };
-
-  // This is a thin wrapper around the thread-tracker's ScopedActivity that
-  // allows thread-safe access to data values. It is safe to use even if
-  // activity tracking is not enabled.
-  class BASE_EXPORT ScopedThreadActivity
-      : public ThreadActivityTracker::ScopedActivity {
-   public:
-    ScopedThreadActivity(const void* program_counter,
-                         const void* origin,
-                         Activity::Type type,
-                         const ActivityData& data,
-                         bool lock_allowed);
-    ~ScopedThreadActivity();
-
-    // Returns an object for manipulating user data.
-    ActivityUserData& user_data();
-
-   private:
-    // Gets (or creates) a tracker for the current thread. If locking is not
-    // allowed (because a lock is being tracked which would cause recursion)
-    // then the attempt to create one if none found will be skipped. Once
-    // the tracker for this thread has been created for other reasons, locks
-    // will be tracked. The thread-tracker uses locks.
-    static ThreadActivityTracker* GetOrCreateTracker(bool lock_allowed) {
-      GlobalActivityTracker* global_tracker = Get();
-      if (!global_tracker)
-        return nullptr;
-      if (lock_allowed)
-        return global_tracker->GetOrCreateTrackerForCurrentThread();
-      else
-        return global_tracker->GetTrackerForCurrentThread();
-    }
-
-    // An object that manages additional user data, created only upon request.
-    std::unique_ptr<ActivityUserData> user_data_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedThreadActivity);
-  };
-
-  ~GlobalActivityTracker();
-
-  // Creates a global tracker using a given persistent-memory |allocator| and
-  // providing the given |stack_depth| to each thread tracker it manages. The
-  // created object is activated so tracking will begin immediately upon return.
-  // The |process_id| can be zero to get it from the OS but is taken for testing
-  // purposes.
-  static void CreateWithAllocator(
-      std::unique_ptr<PersistentMemoryAllocator> allocator,
-      int stack_depth,
-      int64_t process_id);
-
-#if !defined(OS_NACL)
-  // Like above but internally creates an allocator around a disk file with
-  // the specified |size| at the given |file_path|. Any existing file will be
-  // overwritten. The |id| and |name| are arbitrary and stored in the allocator
-  // for reference by whatever process reads it. Returns true if successful.
-  static bool CreateWithFile(const FilePath& file_path,
-                             size_t size,
-                             uint64_t id,
-                             StringPiece name,
-                             int stack_depth);
-#endif  // !defined(OS_NACL)
-
-  // Like above but internally creates an allocator using local heap memory of
-  // the specified size. This is used primarily for unit tests. The |process_id|
-  // can be zero to get it from the OS but is taken for testing purposes.
-  static bool CreateWithLocalMemory(size_t size,
-                                    uint64_t id,
-                                    StringPiece name,
-                                    int stack_depth,
-                                    int64_t process_id);
-
-  // Like above but internally creates an allocator using a shared-memory
-  // segment. The segment must already be mapped into the local memory space.
-  static bool CreateWithSharedMemory(std::unique_ptr<SharedMemory> shm,
-                                     uint64_t id,
-                                     StringPiece name,
-                                     int stack_depth);
-
-  // Like above but takes a handle to an existing shared memory segment and
-  // maps it before creating the tracker.
-  static bool CreateWithSharedMemoryHandle(const SharedMemoryHandle& handle,
-                                           size_t size,
-                                           uint64_t id,
-                                           StringPiece name,
-                                           int stack_depth);
-
-  // Gets the global activity-tracker or null if none exists.
-  static GlobalActivityTracker* Get() {
-    return reinterpret_cast<GlobalActivityTracker*>(
-        subtle::Acquire_Load(&g_tracker_));
-  }
-
-  // Sets the global activity-tracker for testing purposes.
-  static void SetForTesting(std::unique_ptr<GlobalActivityTracker> tracker);
-
-  // This access to the persistent allocator is only for testing; it extracts
-  // the global tracker completely. All tracked threads must exit before
-  // calling this. Tracking for the current thread will be automatically
-  // stopped.
-  static std::unique_ptr<GlobalActivityTracker> ReleaseForTesting();
-
-  // Convenience method for determining if a global tracker is active.
-  static bool IsEnabled() { return Get() != nullptr; }
-
-  // Gets the persistent-memory-allocator in which data is stored. Callers
-  // can store additional records here to pass more information to the
-  // analysis process.
-  PersistentMemoryAllocator* allocator() { return allocator_.get(); }
-
-  // Gets the thread's activity-tracker if it exists. This is inline for
-  // performance reasons and it uses thread-local-storage (TLS) so that there
-  // is no significant lookup time required to find the one for the calling
-  // thread. Ownership remains with the global tracker.
-  ThreadActivityTracker* GetTrackerForCurrentThread() {
-    return reinterpret_cast<ThreadActivityTracker*>(this_thread_tracker_.Get());
-  }
-
-  // Gets the thread's activity-tracker or creates one if none exists. This
-  // is inline for performance reasons. Ownership remains with the global
-  // tracker.
-  ThreadActivityTracker* GetOrCreateTrackerForCurrentThread() {
-    ThreadActivityTracker* tracker = GetTrackerForCurrentThread();
-    if (tracker)
-      return tracker;
-    return CreateTrackerForCurrentThread();
-  }
-
-  // Creates an activity-tracker for the current thread.
-  ThreadActivityTracker* CreateTrackerForCurrentThread();
-
-  // Releases the activity-tracker for the current thread (for testing only).
-  void ReleaseTrackerForCurrentThreadForTesting();
-
-  // Sets a task-runner that can be used for background work.
-  void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner);
-
-  // Sets an optional callback to be called when a process exits.
-  void SetProcessExitCallback(ProcessExitCallback callback);
-
-  // Manages process lifetimes. These are called by the process that launched
-  // and reaped the subprocess, not the subprocess itself. If it is expensive
-  // to generate the parameters, Get() the global tracker and call these
-  // conditionally rather than using the static versions.
-  void RecordProcessLaunch(ProcessId process_id,
-                           const FilePath::StringType& cmd);
-  void RecordProcessLaunch(ProcessId process_id,
-                           const FilePath::StringType& exe,
-                           const FilePath::StringType& args);
-  void RecordProcessExit(ProcessId process_id, int exit_code);
-  static void RecordProcessLaunchIfEnabled(ProcessId process_id,
-                                           const FilePath::StringType& cmd) {
-    GlobalActivityTracker* tracker = Get();
-    if (tracker)
-      tracker->RecordProcessLaunch(process_id, cmd);
-  }
-  static void RecordProcessLaunchIfEnabled(ProcessId process_id,
-                                           const FilePath::StringType& exe,
-                                           const FilePath::StringType& args) {
-    GlobalActivityTracker* tracker = Get();
-    if (tracker)
-      tracker->RecordProcessLaunch(process_id, exe, args);
-  }
-  static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) {
-    GlobalActivityTracker* tracker = Get();
-    if (tracker)
-      tracker->RecordProcessExit(process_id, exit_code);
-  }
-
-  // Sets the "phase" of the current process, useful for knowing what it was
-  // doing when it last reported.
-  void SetProcessPhase(ProcessPhase phase);
-  static void SetProcessPhaseIfEnabled(ProcessPhase phase) {
-    GlobalActivityTracker* tracker = Get();
-    if (tracker)
-      tracker->SetProcessPhase(phase);
-  }
-
-  // Records a log message. The current implementation does NOT recycle these
-  // only store critical messages such as FATAL ones.
-  void RecordLogMessage(StringPiece message);
-  static void RecordLogMessageIfEnabled(StringPiece message) {
-    GlobalActivityTracker* tracker = Get();
-    if (tracker)
-      tracker->RecordLogMessage(message);
-  }
-
-  // Records a module load/unload event. This is safe to call multiple times
-  // even with the same information.
-  void RecordModuleInfo(const ModuleInfo& info);
-  static void RecordModuleInfoIfEnabled(const ModuleInfo& info) {
-    GlobalActivityTracker* tracker = Get();
-    if (tracker)
-      tracker->RecordModuleInfo(info);
-  }
-
-  // Record field trial information. This call is thread-safe. In addition to
-  // this, construction of a GlobalActivityTracker will cause all existing
-  // active field trials to be fetched and recorded.
-  void RecordFieldTrial(const std::string& trial_name, StringPiece group_name);
-  static void RecordFieldTrialIfEnabled(const std::string& trial_name,
-                                        StringPiece group_name) {
-    GlobalActivityTracker* tracker = Get();
-    if (tracker)
-      tracker->RecordFieldTrial(trial_name, group_name);
-  }
-
-  // Record exception information for the current thread.
-  ALWAYS_INLINE
-  void RecordException(const void* origin, uint32_t code) {
-    return RecordExceptionImpl(GetProgramCounter(), origin, code);
-  }
-  void RecordException(const void* pc, const void* origin, uint32_t code);
-
-  // Marks the tracked data as deleted.
-  void MarkDeleted();
-
-  // Gets the process ID used for tracking. This is typically the same as what
-  // the OS thinks is the current process but can be overridden for testing.
-  int64_t process_id() { return process_id_; }
-
-  // Accesses the process data record for storing arbitrary key/value pairs.
-  // Updates to this are thread-safe.
-  ActivityUserData& process_data() { return process_data_; }
-
- private:
-  friend class GlobalActivityAnalyzer;
-  friend class ScopedThreadActivity;
-  friend class ActivityTrackerTest;
-
-  enum : int {
-    // The maximum number of threads that can be tracked within a process. If
-    // more than this number run concurrently, tracking of new ones may cease.
-    kMaxThreadCount = 100,
-    kCachedThreadMemories = 10,
-    kCachedUserDataMemories = 10,
-  };
-
-  // A wrapper around ActivityUserData that is thread-safe and thus can be used
-  // in the global scope without the requirement of being called from only one
-  // thread.
-  class ThreadSafeUserData : public ActivityUserData {
-   public:
-    ThreadSafeUserData(void* memory, size_t size, int64_t pid = 0);
-    ~ThreadSafeUserData() override;
-
-   private:
-    void Set(StringPiece name,
-             ValueType type,
-             const void* memory,
-             size_t size) override;
-
-    Lock data_lock_;
-
-    DISALLOW_COPY_AND_ASSIGN(ThreadSafeUserData);
-  };
-
-  // State of a module as stored in persistent memory. This supports a single
-  // loading of a module only. If modules are loaded multiple times at
-  // different addresses, only the last will be recorded and an unload will
-  // not revert to the information of any other addresses.
-  struct BASE_EXPORT ModuleInfoRecord {
-    // SHA1(ModuleInfoRecord): Increment this if structure changes!
-    static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1;
-
-    // Expected size for 32/64-bit check by PersistentMemoryAllocator.
-    static constexpr size_t kExpectedInstanceSize =
-        OwningProcess::kExpectedInstanceSize + 56;
-
-    // The atomic unfortunately makes this a "complex" class on some compilers
-    // and thus requires an out-of-line constructor & destructor even though
-    // they do nothing.
-    ModuleInfoRecord();
-    ~ModuleInfoRecord();
-
-    OwningProcess owner;            // The process that created this record.
-    uint64_t address;               // The base address of the module.
-    uint64_t load_time;             // Time of last load/unload.
-    uint64_t size;                  // The size of the module in bytes.
-    uint32_t timestamp;             // Opaque timestamp of the module.
-    uint32_t age;                   // Opaque "age" associated with the module.
-    uint8_t identifier[16];         // Opaque identifier for the module.
-    std::atomic<uint32_t> changes;  // Number load/unload actions.
-    uint16_t pickle_size;           // The size of the following pickle.
-    uint8_t loaded;                 // Flag if module is loaded or not.
-    char pickle[1];                 // Other strings; may allocate larger.
-
-    // Decodes/encodes storage structure from more generic info structure.
-    bool DecodeTo(GlobalActivityTracker::ModuleInfo* info,
-                  size_t record_size) const;
-    static ModuleInfoRecord* CreateFrom(
-        const GlobalActivityTracker::ModuleInfo& info,
-        PersistentMemoryAllocator* allocator);
-
-    // Updates the core information without changing the encoded strings. This
-    // is useful when a known module changes state (i.e. new load or unload).
-    bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info);
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord);
-  };
-
-  // A thin wrapper around the main thread-tracker that keeps additional
-  // information that the global tracker needs to handle joined threads.
-  class ManagedActivityTracker : public ThreadActivityTracker {
-   public:
-    ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference,
-                           void* base,
-                           size_t size);
-    ~ManagedActivityTracker() override;
-
-    // The reference into persistent memory from which the thread-tracker's
-    // memory was created.
-    const PersistentMemoryAllocator::Reference mem_reference_;
-
-    // The physical address used for the thread-tracker's memory.
-    void* const mem_base_;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(ManagedActivityTracker);
-  };
-
-  // Creates a global tracker using a given persistent-memory |allocator| and
-  // providing the given |stack_depth| to each thread tracker it manages. The
-  // created object is activated so tracking has already started upon return.
-  // The |process_id| can be zero to get it from the OS but is taken for testing
-  // purposes.
-  GlobalActivityTracker(std::unique_ptr<PersistentMemoryAllocator> allocator,
-                        int stack_depth,
-                        int64_t process_id);
-
-  // Returns the memory used by an activity-tracker managed by this class.
-  // It is called during the destruction of a ManagedActivityTracker object.
-  void ReturnTrackerMemory(ManagedActivityTracker* tracker);
-
-  // Records exception information.
-  void RecordExceptionImpl(const void* pc, const void* origin, uint32_t code);
-
-  // Releases the activity-tracker associcated with thread. It is called
-  // automatically when a thread is joined and thus there is nothing more to
-  // be tracked. |value| is a pointer to a ManagedActivityTracker.
-  static void OnTLSDestroy(void* value);
-
-  // Does process-exit work. This can be run on any thread.
-  void CleanupAfterProcess(int64_t process_id,
-                           int64_t exit_stamp,
-                           int exit_code,
-                           std::string&& command_line);
-
-  // The persistent-memory allocator from which the memory for all trackers
-  // is taken.
-  std::unique_ptr<PersistentMemoryAllocator> allocator_;
-
-  // The size (in bytes) of memory required by a ThreadActivityTracker to
-  // provide the stack-depth requested during construction.
-  const size_t stack_memory_size_;
-
-  // The process-id of the current process. This is kept as a member variable,
-  // defined during initialization, for testing purposes.
-  const int64_t process_id_;
-
-  // The activity tracker for the currently executing thread.
-  ThreadLocalStorage::Slot this_thread_tracker_;
-
-  // The number of thread trackers currently active.
-  std::atomic<int> thread_tracker_count_;
-
-  // A caching memory allocator for thread-tracker objects.
-  ActivityTrackerMemoryAllocator thread_tracker_allocator_;
-  Lock thread_tracker_allocator_lock_;
-
-  // A caching memory allocator for user data attached to activity data.
-  ActivityTrackerMemoryAllocator user_data_allocator_;
-  Lock user_data_allocator_lock_;
-
-  // An object for holding arbitrary key value pairs with thread-safe access.
-  ThreadSafeUserData process_data_;
-
-  // A map of global module information, keyed by module path.
-  std::map<const std::string, ModuleInfoRecord*> modules_;
-  Lock modules_lock_;
-
-  // The active global activity tracker.
-  static subtle::AtomicWord g_tracker_;
-
-  // A lock that is used to protect access to the following fields.
-  Lock global_tracker_lock_;
-
-  // The collection of processes being tracked and their command-lines.
-  std::map<int64_t, std::string> known_processes_;
-
-  // A task-runner that can be used for doing background processing.
-  scoped_refptr<TaskRunner> background_task_runner_;
-
-  // A callback performed when a subprocess exits, including its exit-code
-  // and the phase it was in when that occurred. This will be called via
-  // the |background_task_runner_| if one is set or whatever thread reaped
-  // the process otherwise.
-  ProcessExitCallback process_exit_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
-};
-
-
-// Record entry in to and out of an arbitrary block of code.
-class BASE_EXPORT ScopedActivity
-    : public GlobalActivityTracker::ScopedThreadActivity {
- public:
-  // Track activity at the specified FROM_HERE location for an arbitrary
-  // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary
-  // |info|. None of these values affect operation; they're all purely
-  // for association and analysis. To have unique identifiers across a
-  // diverse code-base, create the number by taking the first 8 characters
-  // of the hash of the activity being tracked.
-  //
-  // For example:
-  //   Tracking method: void MayNeverExit(uint32_t foo) {...}
-  //   echo -n "MayNeverExit" | sha1sum   =>   e44873ccab21e2b71270da24aa1...
-  //
-  //   void MayNeverExit(int32_t foo) {
-  //     base::debug::ScopedActivity track_me(0, 0xE44873CC, foo);
-  //     ...
-  //   }
-  ALWAYS_INLINE
-  ScopedActivity(uint8_t action, uint32_t id, int32_t info)
-      : ScopedActivity(GetProgramCounter(), action, id, info) {}
-  ScopedActivity() : ScopedActivity(0, 0, 0) {}
-
-  // Changes the |action| and/or |info| of this activity on the stack. This
-  // is useful for tracking progress through a function, updating the action
-  // to indicate "milestones" in the block (max 16 milestones: 0-15) or the
-  // info to reflect other changes. Changing both is not atomic so a snapshot
-  // operation could occur between the update of |action| and |info|.
-  void ChangeAction(uint8_t action);
-  void ChangeInfo(int32_t info);
-  void ChangeActionAndInfo(uint8_t action, int32_t info);
-
- private:
-  // Constructs the object using a passed-in program-counter.
-  ScopedActivity(const void* program_counter,
-                 uint8_t action,
-                 uint32_t id,
-                 int32_t info);
-
-  // A copy of the ID code so it doesn't have to be passed by the caller when
-  // changing the |info| field.
-  uint32_t id_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedActivity);
-};
-
-
-// These "scoped" classes provide easy tracking of various blocking actions.
-
-class BASE_EXPORT ScopedTaskRunActivity
-    : public GlobalActivityTracker::ScopedThreadActivity {
- public:
-  ALWAYS_INLINE
-  explicit ScopedTaskRunActivity(const PendingTask& task)
-      : ScopedTaskRunActivity(GetProgramCounter(), task) {}
-
- private:
-  ScopedTaskRunActivity(const void* program_counter, const PendingTask& task);
-  DISALLOW_COPY_AND_ASSIGN(ScopedTaskRunActivity);
-};
-
-class BASE_EXPORT ScopedLockAcquireActivity
-    : public GlobalActivityTracker::ScopedThreadActivity {
- public:
-  ALWAYS_INLINE
-  explicit ScopedLockAcquireActivity(const base::internal::LockImpl* lock)
-      : ScopedLockAcquireActivity(GetProgramCounter(), lock) {}
-
- private:
-  ScopedLockAcquireActivity(const void* program_counter,
-                            const base::internal::LockImpl* lock);
-  DISALLOW_COPY_AND_ASSIGN(ScopedLockAcquireActivity);
-};
-
-class BASE_EXPORT ScopedEventWaitActivity
-    : public GlobalActivityTracker::ScopedThreadActivity {
- public:
-  ALWAYS_INLINE
-  explicit ScopedEventWaitActivity(const WaitableEvent* event)
-      : ScopedEventWaitActivity(GetProgramCounter(), event) {}
-
- private:
-  ScopedEventWaitActivity(const void* program_counter,
-                          const WaitableEvent* event);
-  DISALLOW_COPY_AND_ASSIGN(ScopedEventWaitActivity);
-};
-
-class BASE_EXPORT ScopedThreadJoinActivity
-    : public GlobalActivityTracker::ScopedThreadActivity {
- public:
-  ALWAYS_INLINE
-  explicit ScopedThreadJoinActivity(const PlatformThreadHandle* thread)
-      : ScopedThreadJoinActivity(GetProgramCounter(), thread) {}
-
- private:
-  ScopedThreadJoinActivity(const void* program_counter,
-                           const PlatformThreadHandle* thread);
-  DISALLOW_COPY_AND_ASSIGN(ScopedThreadJoinActivity);
-};
-
-// Some systems don't have base::Process
-#if !defined(OS_NACL) && !defined(OS_IOS)
-class BASE_EXPORT ScopedProcessWaitActivity
-    : public GlobalActivityTracker::ScopedThreadActivity {
- public:
-  ALWAYS_INLINE
-  explicit ScopedProcessWaitActivity(const Process* process)
-      : ScopedProcessWaitActivity(GetProgramCounter(), process) {}
-
- private:
-  ScopedProcessWaitActivity(const void* program_counter,
-                            const Process* process);
-  DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
-};
-#endif
-
-}  // namespace debug
-}  // namespace base
-
-#endif  // BASE_DEBUG_ACTIVITY_TRACKER_H_
diff --git a/base/debug/task_annotator.cc b/base/debug/task_annotator.cc
index def2d7a..69b9c04 100644
--- a/base/debug/task_annotator.cc
+++ b/base/debug/task_annotator.cc
@@ -6,7 +6,6 @@
 
 #include <array>
 
-#include "base/debug/activity_tracker.h"
 #include "base/debug/alias.h"
 #include "base/no_destructor.h"
 #include "base/pending_task.h"
@@ -54,8 +53,6 @@
 
 void TaskAnnotator::RunTask(const char* queue_function,
                             PendingTask* pending_task) {
-  ScopedTaskRunActivity task_activity(*pending_task);
-
   // Before running the task, store the task backtrace with the chain of
   // PostTasks that resulted in this call and deliberately alias it to ensure
   // it is on the stack if the task crashes. Be careful not to assume that the
diff --git a/base/feature_list.cc b/base/feature_list.cc
deleted file mode 100644
index 1610eec..0000000
--- a/base/feature_list.cc
+++ /dev/null
@@ -1,438 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/feature_list.h"
-
-#include <stddef.h>
-
-#include <utility>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/field_trial.h"
-#include "base/pickle.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-
-namespace base {
-
-namespace {
-
-// Pointer to the FeatureList instance singleton that was set via
-// FeatureList::SetInstance(). Does not use base/memory/singleton.h in order to
-// have more control over initialization timing. Leaky.
-FeatureList* g_feature_list_instance = nullptr;
-
-// Tracks whether the FeatureList instance was initialized via an accessor.
-bool g_initialized_from_accessor = false;
-
-// An allocator entry for a feature in shared memory. The FeatureEntry is
-// followed by a base::Pickle object that contains the feature and trial name.
-struct FeatureEntry {
-  // SHA1(FeatureEntry): Increment this if structure changes!
-  static constexpr uint32_t kPersistentTypeId = 0x06567CA6 + 1;
-
-  // Expected size for 32/64-bit check.
-  static constexpr size_t kExpectedInstanceSize = 8;
-
-  // Specifies whether a feature override enables or disables the feature. Same
-  // values as the OverrideState enum in feature_list.h
-  uint32_t override_state;
-
-  // Size of the pickled structure, NOT the total size of this entry.
-  uint32_t pickle_size;
-
-  // Reads the feature and trial name from the pickle. Calling this is only
-  // valid on an initialized entry that's in shared memory.
-  bool GetFeatureAndTrialName(StringPiece* feature_name,
-                              StringPiece* trial_name) const {
-    const char* src =
-        reinterpret_cast<const char*>(this) + sizeof(FeatureEntry);
-
-    Pickle pickle(src, pickle_size);
-    PickleIterator pickle_iter(pickle);
-
-    if (!pickle_iter.ReadStringPiece(feature_name))
-      return false;
-
-    // Return true because we are not guaranteed to have a trial name anyways.
-    auto sink = pickle_iter.ReadStringPiece(trial_name);
-    ALLOW_UNUSED_LOCAL(sink);
-    return true;
-  }
-};
-
-// Some characters are not allowed to appear in feature names or the associated
-// field trial names, as they are used as special characters for command-line
-// serialization. This function checks that the strings are ASCII (since they
-// are used in command-line API functions that require ASCII) and whether there
-// are any reserved characters present, returning true if the string is valid.
-// Only called in DCHECKs.
-bool IsValidFeatureOrFieldTrialName(const std::string& name) {
-  return IsStringASCII(name) && name.find_first_of(",<*") == std::string::npos;
-}
-
-}  // namespace
-
-#if DCHECK_IS_CONFIGURABLE
-const Feature kDCheckIsFatalFeature{"DcheckIsFatal",
-                                    base::FEATURE_DISABLED_BY_DEFAULT};
-#endif  // DCHECK_IS_CONFIGURABLE
-
-FeatureList::FeatureList() = default;
-
-FeatureList::~FeatureList() = default;
-
-void FeatureList::InitializeFromCommandLine(
-    const std::string& enable_features,
-    const std::string& disable_features) {
-  DCHECK(!initialized_);
-
-  // Process disabled features first, so that disabled ones take precedence over
-  // enabled ones (since RegisterOverride() uses insert()).
-  RegisterOverridesFromCommandLine(disable_features, OVERRIDE_DISABLE_FEATURE);
-  RegisterOverridesFromCommandLine(enable_features, OVERRIDE_ENABLE_FEATURE);
-
-  initialized_from_command_line_ = true;
-}
-
-void FeatureList::InitializeFromSharedMemory(
-    PersistentMemoryAllocator* allocator) {
-  DCHECK(!initialized_);
-
-  PersistentMemoryAllocator::Iterator iter(allocator);
-  const FeatureEntry* entry;
-  while ((entry = iter.GetNextOfObject<FeatureEntry>()) != nullptr) {
-    OverrideState override_state =
-        static_cast<OverrideState>(entry->override_state);
-
-    StringPiece feature_name;
-    StringPiece trial_name;
-    if (!entry->GetFeatureAndTrialName(&feature_name, &trial_name))
-      continue;
-
-    FieldTrial* trial = FieldTrialList::Find(trial_name.as_string());
-    RegisterOverride(feature_name, override_state, trial);
-  }
-}
-
-bool FeatureList::IsFeatureOverriddenFromCommandLine(
-    const std::string& feature_name,
-    OverrideState state) const {
-  auto it = overrides_.find(feature_name);
-  return it != overrides_.end() && it->second.overridden_state == state &&
-         !it->second.overridden_by_field_trial;
-}
-
-void FeatureList::AssociateReportingFieldTrial(
-    const std::string& feature_name,
-    OverrideState for_overridden_state,
-    FieldTrial* field_trial) {
-  DCHECK(
-      IsFeatureOverriddenFromCommandLine(feature_name, for_overridden_state));
-
-  // Only one associated field trial is supported per feature. This is generally
-  // enforced server-side.
-  OverrideEntry* entry = &overrides_.find(feature_name)->second;
-  if (entry->field_trial) {
-    NOTREACHED() << "Feature " << feature_name
-                 << " already has trial: " << entry->field_trial->trial_name()
-                 << ", associating trial: " << field_trial->trial_name();
-    return;
-  }
-
-  entry->field_trial = field_trial;
-}
-
-void FeatureList::RegisterFieldTrialOverride(const std::string& feature_name,
-                                             OverrideState override_state,
-                                             FieldTrial* field_trial) {
-  DCHECK(field_trial);
-  DCHECK(!ContainsKey(overrides_, feature_name) ||
-         !overrides_.find(feature_name)->second.field_trial)
-      << "Feature " << feature_name
-      << " has conflicting field trial overrides: "
-      << overrides_.find(feature_name)->second.field_trial->trial_name()
-      << " / " << field_trial->trial_name();
-
-  RegisterOverride(feature_name, override_state, field_trial);
-}
-
-void FeatureList::AddFeaturesToAllocator(PersistentMemoryAllocator* allocator) {
-  DCHECK(initialized_);
-
-  for (const auto& override : overrides_) {
-    Pickle pickle;
-    pickle.WriteString(override.first);
-    if (override.second.field_trial)
-      pickle.WriteString(override.second.field_trial->trial_name());
-
-    size_t total_size = sizeof(FeatureEntry) + pickle.size();
-    FeatureEntry* entry = allocator->New<FeatureEntry>(total_size);
-    if (!entry)
-      return;
-
-    entry->override_state = override.second.overridden_state;
-    entry->pickle_size = pickle.size();
-
-    char* dst = reinterpret_cast<char*>(entry) + sizeof(FeatureEntry);
-    memcpy(dst, pickle.data(), pickle.size());
-
-    allocator->MakeIterable(entry);
-  }
-}
-
-void FeatureList::GetFeatureOverrides(std::string* enable_overrides,
-                                      std::string* disable_overrides) {
-  GetFeatureOverridesImpl(enable_overrides, disable_overrides, false);
-}
-
-void FeatureList::GetCommandLineFeatureOverrides(
-    std::string* enable_overrides,
-    std::string* disable_overrides) {
-  GetFeatureOverridesImpl(enable_overrides, disable_overrides, true);
-}
-
-// static
-bool FeatureList::IsEnabled(const Feature& feature) {
-  if (!g_feature_list_instance) {
-    g_initialized_from_accessor = true;
-    return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
-  }
-  return g_feature_list_instance->IsFeatureEnabled(feature);
-}
-
-// static
-FieldTrial* FeatureList::GetFieldTrial(const Feature& feature) {
-  if (!g_feature_list_instance) {
-    g_initialized_from_accessor = true;
-    return nullptr;
-  }
-  return g_feature_list_instance->GetAssociatedFieldTrial(feature);
-}
-
-// static
-std::vector<base::StringPiece> FeatureList::SplitFeatureListString(
-    base::StringPiece input) {
-  return SplitStringPiece(input, ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
-}
-
-// static
-bool FeatureList::InitializeInstance(const std::string& enable_features,
-                                     const std::string& disable_features) {
-  // We want to initialize a new instance here to support command-line features
-  // in testing better. For example, we initialize a dummy instance in
-  // base/test/test_suite.cc, and override it in content/browser/
-  // browser_main_loop.cc.
-  // On the other hand, we want to avoid re-initialization from command line.
-  // For example, we initialize an instance in chrome/browser/
-  // chrome_browser_main.cc and do not override it in content/browser/
-  // browser_main_loop.cc.
-  // If the singleton was previously initialized from within an accessor, we
-  // want to prevent callers from reinitializing the singleton and masking the
-  // accessor call(s) which likely returned incorrect information.
-  CHECK(!g_initialized_from_accessor);
-  bool instance_existed_before = false;
-  if (g_feature_list_instance) {
-    if (g_feature_list_instance->initialized_from_command_line_)
-      return false;
-
-    delete g_feature_list_instance;
-    g_feature_list_instance = nullptr;
-    instance_existed_before = true;
-  }
-
-  std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
-  feature_list->InitializeFromCommandLine(enable_features, disable_features);
-  base::FeatureList::SetInstance(std::move(feature_list));
-  return !instance_existed_before;
-}
-
-// static
-FeatureList* FeatureList::GetInstance() {
-  return g_feature_list_instance;
-}
-
-// static
-void FeatureList::SetInstance(std::unique_ptr<FeatureList> instance) {
-  DCHECK(!g_feature_list_instance);
-  instance->FinalizeInitialization();
-
-  // Note: Intentional leak of global singleton.
-  g_feature_list_instance = instance.release();
-
-#if DCHECK_IS_CONFIGURABLE
-  // Update the behaviour of LOG_DCHECK to match the Feature configuration.
-  // DCHECK is also forced to be FATAL if we are running a death-test.
-  // TODO(asvitkine): If we find other use-cases that need integrating here
-  // then define a proper API/hook for the purpose.
-  if (base::FeatureList::IsEnabled(kDCheckIsFatalFeature) ||
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          "gtest_internal_run_death_test")) {
-    logging::LOG_DCHECK = logging::LOG_FATAL;
-  } else {
-    logging::LOG_DCHECK = logging::LOG_INFO;
-  }
-#endif  // DCHECK_IS_CONFIGURABLE
-}
-
-// static
-std::unique_ptr<FeatureList> FeatureList::ClearInstanceForTesting() {
-  FeatureList* old_instance = g_feature_list_instance;
-  g_feature_list_instance = nullptr;
-  g_initialized_from_accessor = false;
-  return base::WrapUnique(old_instance);
-}
-
-// static
-void FeatureList::RestoreInstanceForTesting(
-    std::unique_ptr<FeatureList> instance) {
-  DCHECK(!g_feature_list_instance);
-  // Note: Intentional leak of global singleton.
-  g_feature_list_instance = instance.release();
-}
-
-void FeatureList::FinalizeInitialization() {
-  DCHECK(!initialized_);
-  initialized_ = true;
-}
-
-bool FeatureList::IsFeatureEnabled(const Feature& feature) {
-  DCHECK(initialized_);
-  DCHECK(IsValidFeatureOrFieldTrialName(feature.name)) << feature.name;
-  DCHECK(CheckFeatureIdentity(feature)) << feature.name;
-
-  auto it = overrides_.find(feature.name);
-  if (it != overrides_.end()) {
-    const OverrideEntry& entry = it->second;
-
-    // Activate the corresponding field trial, if necessary.
-    if (entry.field_trial)
-      entry.field_trial->group();
-
-    // TODO(asvitkine) Expand this section as more support is added.
-
-    // If marked as OVERRIDE_USE_DEFAULT, simply return the default state below.
-    if (entry.overridden_state != OVERRIDE_USE_DEFAULT)
-      return entry.overridden_state == OVERRIDE_ENABLE_FEATURE;
-  }
-  // Otherwise, return the default state.
-  return feature.default_state == FEATURE_ENABLED_BY_DEFAULT;
-}
-
-FieldTrial* FeatureList::GetAssociatedFieldTrial(const Feature& feature) {
-  DCHECK(initialized_);
-  DCHECK(IsValidFeatureOrFieldTrialName(feature.name)) << feature.name;
-  DCHECK(CheckFeatureIdentity(feature)) << feature.name;
-
-  auto it = overrides_.find(feature.name);
-  if (it != overrides_.end()) {
-    const OverrideEntry& entry = it->second;
-    return entry.field_trial;
-  }
-
-  return nullptr;
-}
-
-void FeatureList::RegisterOverridesFromCommandLine(
-    const std::string& feature_list,
-    OverrideState overridden_state) {
-  for (const auto& value : SplitFeatureListString(feature_list)) {
-    StringPiece feature_name = value;
-    base::FieldTrial* trial = nullptr;
-
-    // The entry may be of the form FeatureName<FieldTrialName - in which case,
-    // this splits off the field trial name and associates it with the override.
-    std::string::size_type pos = feature_name.find('<');
-    if (pos != std::string::npos) {
-      feature_name.set(value.data(), pos);
-      trial = base::FieldTrialList::Find(value.substr(pos + 1).as_string());
-    }
-
-    RegisterOverride(feature_name, overridden_state, trial);
-  }
-}
-
-void FeatureList::RegisterOverride(StringPiece feature_name,
-                                   OverrideState overridden_state,
-                                   FieldTrial* field_trial) {
-  DCHECK(!initialized_);
-  if (field_trial) {
-    DCHECK(IsValidFeatureOrFieldTrialName(field_trial->trial_name()))
-        << field_trial->trial_name();
-  }
-  if (feature_name.starts_with("*")) {
-    feature_name = feature_name.substr(1);
-    overridden_state = OVERRIDE_USE_DEFAULT;
-  }
-
-  // Note: The semantics of insert() is that it does not overwrite the entry if
-  // one already exists for the key. Thus, only the first override for a given
-  // feature name takes effect.
-  overrides_.insert(std::make_pair(
-      feature_name.as_string(), OverrideEntry(overridden_state, field_trial)));
-}
-
-void FeatureList::GetFeatureOverridesImpl(std::string* enable_overrides,
-                                          std::string* disable_overrides,
-                                          bool command_line_only) {
-  DCHECK(initialized_);
-
-  enable_overrides->clear();
-  disable_overrides->clear();
-
-  // Note: Since |overrides_| is a std::map, iteration will be in alphabetical
-  // order. This is not guaranteed to users of this function, but is useful for
-  // tests to assume the order.
-  for (const auto& entry : overrides_) {
-    if (command_line_only &&
-        (entry.second.field_trial != nullptr ||
-         entry.second.overridden_state == OVERRIDE_USE_DEFAULT)) {
-      continue;
-    }
-
-    std::string* target_list = nullptr;
-    switch (entry.second.overridden_state) {
-      case OVERRIDE_USE_DEFAULT:
-      case OVERRIDE_ENABLE_FEATURE:
-        target_list = enable_overrides;
-        break;
-      case OVERRIDE_DISABLE_FEATURE:
-        target_list = disable_overrides;
-        break;
-    }
-
-    if (!target_list->empty())
-      target_list->push_back(',');
-    if (entry.second.overridden_state == OVERRIDE_USE_DEFAULT)
-      target_list->push_back('*');
-    target_list->append(entry.first);
-    if (entry.second.field_trial) {
-      target_list->push_back('<');
-      target_list->append(entry.second.field_trial->trial_name());
-    }
-  }
-}
-
-bool FeatureList::CheckFeatureIdentity(const Feature& feature) {
-  AutoLock auto_lock(feature_identity_tracker_lock_);
-
-  auto it = feature_identity_tracker_.find(feature.name);
-  if (it == feature_identity_tracker_.end()) {
-    // If it's not tracked yet, register it.
-    feature_identity_tracker_[feature.name] = &feature;
-    return true;
-  }
-  // Compare address of |feature| to the existing tracked entry.
-  return it->second == &feature;
-}
-
-FeatureList::OverrideEntry::OverrideEntry(OverrideState overridden_state,
-                                          FieldTrial* field_trial)
-    : overridden_state(overridden_state),
-      field_trial(field_trial),
-      overridden_by_field_trial(field_trial != nullptr) {}
-
-}  // namespace base
diff --git a/base/feature_list.h b/base/feature_list.h
deleted file mode 100644
index 2237507..0000000
--- a/base/feature_list.h
+++ /dev/null
@@ -1,310 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_FEATURE_LIST_H_
-#define BASE_FEATURE_LIST_H_
-
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/metrics/persistent_memory_allocator.h"
-#include "base/strings/string_piece.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-class FieldTrial;
-
-// Specifies whether a given feature is enabled or disabled by default.
-enum FeatureState {
-  FEATURE_DISABLED_BY_DEFAULT,
-  FEATURE_ENABLED_BY_DEFAULT,
-};
-
-// The Feature struct is used to define the default state for a feature. See
-// comment below for more details. There must only ever be one struct instance
-// for a given feature name - generally defined as a constant global variable or
-// file static. It should never be used as a constexpr as it breaks
-// pointer-based identity lookup.
-struct BASE_EXPORT Feature {
-  // The name of the feature. This should be unique to each feature and is used
-  // for enabling/disabling features via command line flags and experiments.
-  // It is strongly recommended to use CamelCase style for feature names, e.g.
-  // "MyGreatFeature".
-  const char* const name;
-
-  // The default state (i.e. enabled or disabled) for this feature.
-  const FeatureState default_state;
-};
-
-#if DCHECK_IS_CONFIGURABLE
-// DCHECKs have been built-in, and are configurable at run-time to be fatal, or
-// not, via a DcheckIsFatal feature. We define the Feature here since it is
-// checked in FeatureList::SetInstance(). See https://crbug.com/596231.
-extern BASE_EXPORT const Feature kDCheckIsFatalFeature;
-#endif  // DCHECK_IS_CONFIGURABLE
-
-// The FeatureList class is used to determine whether a given feature is on or
-// off. It provides an authoritative answer, taking into account command-line
-// overrides and experimental control.
-//
-// The basic use case is for any feature that can be toggled (e.g. through
-// command-line or an experiment) to have a defined Feature struct, e.g.:
-//
-//   const base::Feature kMyGreatFeature {
-//     "MyGreatFeature", base::FEATURE_ENABLED_BY_DEFAULT
-//   };
-//
-// Then, client code that wishes to query the state of the feature would check:
-//
-//   if (base::FeatureList::IsEnabled(kMyGreatFeature)) {
-//     // Feature code goes here.
-//   }
-//
-// Behind the scenes, the above call would take into account any command-line
-// flags to enable or disable the feature, any experiments that may control it
-// and finally its default state (in that order of priority), to determine
-// whether the feature is on.
-//
-// Features can be explicitly forced on or off by specifying a list of comma-
-// separated feature names via the following command-line flags:
-//
-//   --enable-features=Feature5,Feature7
-//   --disable-features=Feature1,Feature2,Feature3
-//
-// To enable/disable features in a test, do NOT append --enable-features or
-// --disable-features to the command-line directly. Instead, use
-// ScopedFeatureList. See base/test/scoped_feature_list.h for details.
-//
-// After initialization (which should be done single-threaded), the FeatureList
-// API is thread safe.
-//
-// Note: This class is a singleton, but does not use base/memory/singleton.h in
-// order to have control over its initialization sequence. Specifically, the
-// intended use is to create an instance of this class and fully initialize it,
-// before setting it as the singleton for a process, via SetInstance().
-class BASE_EXPORT FeatureList {
- public:
-  FeatureList();
-  ~FeatureList();
-
-  // Initializes feature overrides via command-line flags |enable_features| and
-  // |disable_features|, each of which is a comma-separated list of features to
-  // enable or disable, respectively. If a feature appears on both lists, then
-  // it will be disabled. If a list entry has the format "FeatureName<TrialName"
-  // then this initialization will also associate the feature state override
-  // with the named field trial, if it exists. If a feature name is prefixed
-  // with the '*' character, it will be created with OVERRIDE_USE_DEFAULT -
-  // which is useful for associating with a trial while using the default state.
-  // Must only be invoked during the initialization phase (before
-  // FinalizeInitialization() has been called).
-  void InitializeFromCommandLine(const std::string& enable_features,
-                                 const std::string& disable_features);
-
-  // Initializes feature overrides through the field trial allocator, which
-  // we're using to store the feature names, their override state, and the name
-  // of the associated field trial.
-  void InitializeFromSharedMemory(PersistentMemoryAllocator* allocator);
-
-  // Specifies whether a feature override enables or disables the feature.
-  enum OverrideState {
-    OVERRIDE_USE_DEFAULT,
-    OVERRIDE_DISABLE_FEATURE,
-    OVERRIDE_ENABLE_FEATURE,
-  };
-
-  // Returns true if the state of |feature_name| has been overridden via
-  // |InitializeFromCommandLine()|.
-  bool IsFeatureOverriddenFromCommandLine(const std::string& feature_name,
-                                          OverrideState state) const;
-
-  // Associates a field trial for reporting purposes corresponding to the
-  // command-line setting the feature state to |for_overridden_state|. The trial
-  // will be activated when the state of the feature is first queried. This
-  // should be called during registration, after InitializeFromCommandLine() has
-  // been called but before the instance is registered via SetInstance().
-  void AssociateReportingFieldTrial(const std::string& feature_name,
-                                    OverrideState for_overridden_state,
-                                    FieldTrial* field_trial);
-
-  // Registers a field trial to override the enabled state of the specified
-  // feature to |override_state|. Command-line overrides still take precedence
-  // over field trials, so this will have no effect if the feature is being
-  // overridden from the command-line. The associated field trial will be
-  // activated when the feature state for this feature is queried. This should
-  // be called during registration, after InitializeFromCommandLine() has been
-  // called but before the instance is registered via SetInstance().
-  void RegisterFieldTrialOverride(const std::string& feature_name,
-                                  OverrideState override_state,
-                                  FieldTrial* field_trial);
-
-  // Loops through feature overrides and serializes them all into |allocator|.
-  void AddFeaturesToAllocator(PersistentMemoryAllocator* allocator);
-
-  // Returns comma-separated lists of feature names (in the same format that is
-  // accepted by InitializeFromCommandLine()) corresponding to features that
-  // have been overridden - either through command-line or via FieldTrials. For
-  // those features that have an associated FieldTrial, the output entry will be
-  // of the format "FeatureName<TrialName", where "TrialName" is the name of the
-  // FieldTrial. Features that have overrides with OVERRIDE_USE_DEFAULT will be
-  // added to |enable_overrides| with a '*' character prefix. Must be called
-  // only after the instance has been initialized and registered.
-  void GetFeatureOverrides(std::string* enable_overrides,
-                           std::string* disable_overrides);
-
-  // Like GetFeatureOverrides(), but only returns overrides that were specified
-  // explicitly on the command-line, omitting the ones from field trials.
-  void GetCommandLineFeatureOverrides(std::string* enable_overrides,
-                                      std::string* disable_overrides);
-
-  // Returns whether the given |feature| is enabled. Must only be called after
-  // the singleton instance has been registered via SetInstance(). Additionally,
-  // a feature with a given name must only have a single corresponding Feature
-  // struct, which is checked in builds with DCHECKs enabled.
-  static bool IsEnabled(const Feature& feature);
-
-  // Returns the field trial associated with the given |feature|. Must only be
-  // called after the singleton instance has been registered via SetInstance().
-  static FieldTrial* GetFieldTrial(const Feature& feature);
-
-  // Splits a comma-separated string containing feature names into a vector. The
-  // resulting pieces point to parts of |input|.
-  static std::vector<base::StringPiece> SplitFeatureListString(
-      base::StringPiece input);
-
-  // Initializes and sets an instance of FeatureList with feature overrides via
-  // command-line flags |enable_features| and |disable_features| if one has not
-  // already been set from command-line flags. Returns true if an instance did
-  // not previously exist. See InitializeFromCommandLine() for more details
-  // about |enable_features| and |disable_features| parameters.
-  static bool InitializeInstance(const std::string& enable_features,
-                                 const std::string& disable_features);
-
-  // Returns the singleton instance of FeatureList. Will return null until an
-  // instance is registered via SetInstance().
-  static FeatureList* GetInstance();
-
-  // Registers the given |instance| to be the singleton feature list for this
-  // process. This should only be called once and |instance| must not be null.
-  // Note: If you are considering using this for the purposes of testing, take
-  // a look at using base/test/scoped_feature_list.h instead.
-  static void SetInstance(std::unique_ptr<FeatureList> instance);
-
-  // Clears the previously-registered singleton instance for tests and returns
-  // the old instance.
-  // Note: Most tests should never call this directly. Instead consider using
-  // base::test::ScopedFeatureList.
-  static std::unique_ptr<FeatureList> ClearInstanceForTesting();
-
-  // Sets a given (initialized) |instance| to be the singleton feature list,
-  // for testing. Existing instance must be null. This is primarily intended
-  // to support base::test::ScopedFeatureList helper class.
-  static void RestoreInstanceForTesting(std::unique_ptr<FeatureList> instance);
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(FeatureListTest, CheckFeatureIdentity);
-  FRIEND_TEST_ALL_PREFIXES(FeatureListTest,
-                           StoreAndRetrieveFeaturesFromSharedMemory);
-  FRIEND_TEST_ALL_PREFIXES(FeatureListTest,
-                           StoreAndRetrieveAssociatedFeaturesFromSharedMemory);
-
-  struct OverrideEntry {
-    // The overridden enable (on/off) state of the feature.
-    const OverrideState overridden_state;
-
-    // An optional associated field trial, which will be activated when the
-    // state of the feature is queried for the first time. Weak pointer to the
-    // FieldTrial object that is owned by the FieldTrialList singleton.
-    base::FieldTrial* field_trial;
-
-    // Specifies whether the feature's state is overridden by |field_trial|.
-    // If it's not, and |field_trial| is not null, it means it is simply an
-    // associated field trial for reporting purposes (and |overridden_state|
-    // came from the command-line).
-    const bool overridden_by_field_trial;
-
-    // TODO(asvitkine): Expand this as more support is added.
-
-    // Constructs an OverrideEntry for the given |overridden_state|. If
-    // |field_trial| is not null, it implies that |overridden_state| comes from
-    // the trial, so |overridden_by_field_trial| will be set to true.
-    OverrideEntry(OverrideState overridden_state, FieldTrial* field_trial);
-  };
-
-  // Finalizes the initialization state of the FeatureList, so that no further
-  // overrides can be registered. This is called by SetInstance() on the
-  // singleton feature list that is being registered.
-  void FinalizeInitialization();
-
-  // Returns whether the given |feature| is enabled. This is invoked by the
-  // public FeatureList::IsEnabled() static function on the global singleton.
-  // Requires the FeatureList to have already been fully initialized.
-  bool IsFeatureEnabled(const Feature& feature);
-
-  // Returns the field trial associated with the given |feature|. This is
-  // invoked by the public FeatureList::GetFieldTrial() static function on the
-  // global singleton. Requires the FeatureList to have already been fully
-  // initialized.
-  base::FieldTrial* GetAssociatedFieldTrial(const Feature& feature);
-
-  // For each feature name in comma-separated list of strings |feature_list|,
-  // registers an override with the specified |overridden_state|. Also, will
-  // associate an optional named field trial if the entry is of the format
-  // "FeatureName<TrialName".
-  void RegisterOverridesFromCommandLine(const std::string& feature_list,
-                                        OverrideState overridden_state);
-
-  // Registers an override for feature |feature_name|. The override specifies
-  // whether the feature should be on or off (via |overridden_state|), which
-  // will take precedence over the feature's default state. If |field_trial| is
-  // not null, registers the specified field trial object to be associated with
-  // the feature, which will activate the field trial when the feature state is
-  // queried. If an override is already registered for the given feature, it
-  // will not be changed.
-  void RegisterOverride(StringPiece feature_name,
-                        OverrideState overridden_state,
-                        FieldTrial* field_trial);
-
-  // Implementation of GetFeatureOverrides() with a parameter that specifies
-  // whether only command-line enabled overrides should be emitted. See that
-  // function's comments for more details.
-  void GetFeatureOverridesImpl(std::string* enable_overrides,
-                               std::string* disable_overrides,
-                               bool command_line_only);
-
-  // Verifies that there's only a single definition of a Feature struct for a
-  // given feature name. Keeps track of the first seen Feature struct for each
-  // feature. Returns false when called on a Feature struct with a different
-  // address than the first one it saw for that feature name. Used only from
-  // DCHECKs and tests.
-  bool CheckFeatureIdentity(const Feature& feature);
-
-  // Map from feature name to an OverrideEntry struct for the feature, if it
-  // exists.
-  std::map<std::string, OverrideEntry> overrides_;
-
-  // Locked map that keeps track of seen features, to ensure a single feature is
-  // only defined once. This verification is only done in builds with DCHECKs
-  // enabled.
-  Lock feature_identity_tracker_lock_;
-  std::map<std::string, const Feature*> feature_identity_tracker_;
-
-  // Whether this object has been fully initialized. This gets set to true as a
-  // result of FinalizeInitialization().
-  bool initialized_ = false;
-
-  // Whether this object has been initialized from command line.
-  bool initialized_from_command_line_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(FeatureList);
-};
-
-}  // namespace base
-
-#endif  // BASE_FEATURE_LIST_H_
diff --git a/base/files/file.cc b/base/files/file.cc
index 92ff6dd..b79802b 100644
--- a/base/files/file.cc
+++ b/base/files/file.cc
@@ -5,7 +5,6 @@
 #include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/files/file_tracing.h"
-#include "base/metrics/histogram.h"
 #include "base/timer/elapsed_timer.h"
 #include "build_config.h"
 
diff --git a/base/files/file_posix.cc b/base/files/file_posix.cc
index d6b7641..9f6ae16 100644
--- a/base/files/file_posix.cc
+++ b/base/files/file_posix.cc
@@ -11,7 +11,6 @@
 #include <unistd.h>
 
 #include "base/logging.h"
-#include "base/metrics/histogram_functions.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_restrictions.h"
@@ -421,9 +420,6 @@
     case ENOTDIR:
       return FILE_ERROR_NOT_A_DIRECTORY;
     default:
-#if !defined(OS_NACL)  // NaCl build has no metrics code.
-      UmaHistogramSparse("PlatformFile.UnknownErrors.Posix", saved_errno);
-#endif
       // This function should only be called for errors.
       DCHECK_NE(0, saved_errno);
       return FILE_ERROR_FAILED;
diff --git a/base/files/important_file_writer.cc b/base/files/important_file_writer.cc
deleted file mode 100644
index 7fd9d79..0000000
--- a/base/files/important_file_writer.cc
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/files/important_file_writer.h"
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/critical_closure.h"
-#include "base/debug/alias.h"
-#include "base/files/file.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/task_runner.h"
-#include "base/task_runner_util.h"
-#include "base/threading/thread.h"
-#include "base/time/time.h"
-#include "build_config.h"
-
-namespace base {
-
-namespace {
-
-constexpr auto kDefaultCommitInterval = TimeDelta::FromSeconds(10);
-
-// This enum is used to define the buckets for an enumerated UMA histogram.
-// Hence,
-//   (a) existing enumerated constants should never be deleted or reordered, and
-//   (b) new constants should only be appended at the end of the enumeration.
-enum TempFileFailure {
-  FAILED_CREATING,
-  FAILED_OPENING,
-  FAILED_CLOSING,  // Unused.
-  FAILED_WRITING,
-  FAILED_RENAMING,
-  FAILED_FLUSHING,
-  TEMP_FILE_FAILURE_MAX
-};
-
-// Helper function to write samples to a histogram with a dynamically assigned
-// histogram name.  Works with different error code types convertible to int
-// which is the actual argument type of UmaHistogramExactLinear.
-template <typename SampleType>
-void UmaHistogramExactLinearWithSuffix(const char* histogram_name,
-                                       StringPiece histogram_suffix,
-                                       SampleType add_sample,
-                                       SampleType max_sample) {
-  static_assert(std::is_convertible<SampleType, int>::value,
-                "SampleType should be convertible to int");
-  DCHECK(histogram_name);
-  std::string histogram_full_name(histogram_name);
-  if (!histogram_suffix.empty()) {
-    histogram_full_name.append(".");
-    histogram_full_name.append(histogram_suffix.data(),
-                               histogram_suffix.length());
-  }
-  UmaHistogramExactLinear(histogram_full_name, static_cast<int>(add_sample),
-                          static_cast<int>(max_sample));
-}
-
-// Helper function to write samples to a histogram with a dynamically assigned
-// histogram name.  Works with short timings from 1 ms up to 10 seconds (50
-// buckets) which is the actual argument type of UmaHistogramTimes.
-void UmaHistogramTimesWithSuffix(const char* histogram_name,
-                                 StringPiece histogram_suffix,
-                                 TimeDelta sample) {
-  DCHECK(histogram_name);
-  std::string histogram_full_name(histogram_name);
-  if (!histogram_suffix.empty()) {
-    histogram_full_name.append(".");
-    histogram_full_name.append(histogram_suffix.data(),
-                               histogram_suffix.length());
-  }
-  UmaHistogramTimes(histogram_full_name, sample);
-}
-
-void LogFailure(const FilePath& path,
-                StringPiece histogram_suffix,
-                TempFileFailure failure_code,
-                StringPiece message) {
-  UmaHistogramExactLinearWithSuffix("ImportantFile.TempFileFailures",
-                                    histogram_suffix, failure_code,
-                                    TEMP_FILE_FAILURE_MAX);
-  DPLOG(WARNING) << "temp file failure: " << path.value() << " : " << message;
-}
-
-// Helper function to call WriteFileAtomically() with a
-// std::unique_ptr<std::string>.
-void WriteScopedStringToFileAtomically(
-    const FilePath& path,
-    std::unique_ptr<std::string> data,
-    Closure before_write_callback,
-    Callback<void(bool success)> after_write_callback,
-    const std::string& histogram_suffix) {
-  if (!before_write_callback.is_null())
-    before_write_callback.Run();
-
-  TimeTicks start_time = TimeTicks::Now();
-  bool result =
-      ImportantFileWriter::WriteFileAtomically(path, *data, histogram_suffix);
-  if (result) {
-    UmaHistogramTimesWithSuffix("ImportantFile.TimeToWrite", histogram_suffix,
-                                TimeTicks::Now() - start_time);
-  }
-
-  if (!after_write_callback.is_null())
-    after_write_callback.Run(result);
-}
-
-void DeleteTmpFile(const FilePath& tmp_file_path,
-                   StringPiece histogram_suffix) {
-  if (!DeleteFile(tmp_file_path, false)) {
-    UmaHistogramExactLinearWithSuffix(
-        "ImportantFile.FileDeleteError", histogram_suffix,
-        -base::File::GetLastFileError(), -base::File::FILE_ERROR_MAX);
-  }
-}
-
-}  // namespace
-
-// static
-bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
-                                              StringPiece data,
-                                              StringPiece histogram_suffix) {
-#if defined(OS_CHROMEOS)
-  // On Chrome OS, chrome gets killed when it cannot finish shutdown quickly,
-  // and this function seems to be one of the slowest shutdown steps.
-  // Include some info to the report for investigation. crbug.com/418627
-  // TODO(hashimoto): Remove this.
-  struct {
-    size_t data_size;
-    char path[128];
-  } file_info;
-  file_info.data_size = data.size();
-  strlcpy(file_info.path, path.value().c_str(), arraysize(file_info.path));
-  debug::Alias(&file_info);
-#endif
-
-  // Write the data to a temp file then rename to avoid data loss if we crash
-  // while writing the file. Ensure that the temp file is on the same volume
-  // as target file, so it can be moved in one step, and that the temp file
-  // is securely created.
-  FilePath tmp_file_path;
-  if (!CreateTemporaryFileInDir(path.DirName(), &tmp_file_path)) {
-    UmaHistogramExactLinearWithSuffix(
-        "ImportantFile.FileCreateError", histogram_suffix,
-        -base::File::GetLastFileError(), -base::File::FILE_ERROR_MAX);
-    LogFailure(path, histogram_suffix, FAILED_CREATING,
-               "could not create temporary file");
-    return false;
-  }
-
-  File tmp_file(tmp_file_path, File::FLAG_OPEN | File::FLAG_WRITE);
-  if (!tmp_file.IsValid()) {
-    UmaHistogramExactLinearWithSuffix(
-        "ImportantFile.FileOpenError", histogram_suffix,
-        -tmp_file.error_details(), -base::File::FILE_ERROR_MAX);
-    LogFailure(path, histogram_suffix, FAILED_OPENING,
-               "could not open temporary file");
-    DeleteFile(tmp_file_path, false);
-    return false;
-  }
-
-  // If this fails in the wild, something really bad is going on.
-  const int data_length = checked_cast<int32_t>(data.length());
-  int bytes_written = tmp_file.Write(0, data.data(), data_length);
-  if (bytes_written < data_length) {
-    UmaHistogramExactLinearWithSuffix(
-        "ImportantFile.FileWriteError", histogram_suffix,
-        -base::File::GetLastFileError(), -base::File::FILE_ERROR_MAX);
-  }
-  bool flush_success = tmp_file.Flush();
-  tmp_file.Close();
-
-  if (bytes_written < data_length) {
-    LogFailure(path, histogram_suffix, FAILED_WRITING,
-               "error writing, bytes_written=" + IntToString(bytes_written));
-    DeleteTmpFile(tmp_file_path, histogram_suffix);
-    return false;
-  }
-
-  if (!flush_success) {
-    LogFailure(path, histogram_suffix, FAILED_FLUSHING, "error flushing");
-    DeleteTmpFile(tmp_file_path, histogram_suffix);
-    return false;
-  }
-
-  base::File::Error replace_file_error = base::File::FILE_OK;
-  if (!ReplaceFile(tmp_file_path, path, &replace_file_error)) {
-    UmaHistogramExactLinearWithSuffix("ImportantFile.FileRenameError",
-                                      histogram_suffix, -replace_file_error,
-                                      -base::File::FILE_ERROR_MAX);
-    LogFailure(path, histogram_suffix, FAILED_RENAMING,
-               "could not rename temporary file");
-    DeleteTmpFile(tmp_file_path, histogram_suffix);
-    return false;
-  }
-
-  return true;
-}
-
-ImportantFileWriter::ImportantFileWriter(
-    const FilePath& path,
-    scoped_refptr<SequencedTaskRunner> task_runner,
-    const char* histogram_suffix)
-    : ImportantFileWriter(path,
-                          std::move(task_runner),
-                          kDefaultCommitInterval,
-                          histogram_suffix) {}
-
-ImportantFileWriter::ImportantFileWriter(
-    const FilePath& path,
-    scoped_refptr<SequencedTaskRunner> task_runner,
-    TimeDelta interval,
-    const char* histogram_suffix)
-    : path_(path),
-      task_runner_(std::move(task_runner)),
-      serializer_(nullptr),
-      commit_interval_(interval),
-      histogram_suffix_(histogram_suffix ? histogram_suffix : ""),
-      weak_factory_(this) {
-  DCHECK(task_runner_);
-}
-
-ImportantFileWriter::~ImportantFileWriter() {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  // We're usually a member variable of some other object, which also tends
-  // to be our serializer. It may not be safe to call back to the parent object
-  // being destructed.
-  DCHECK(!HasPendingWrite());
-}
-
-bool ImportantFileWriter::HasPendingWrite() const {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return timer().IsRunning();
-}
-
-void ImportantFileWriter::WriteNow(std::unique_ptr<std::string> data) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!IsValueInRangeForNumericType<int32_t>(data->length())) {
-    NOTREACHED();
-    return;
-  }
-
-  Closure task = AdaptCallbackForRepeating(
-      BindOnce(&WriteScopedStringToFileAtomically, path_, std::move(data),
-               std::move(before_next_write_callback_),
-               std::move(after_next_write_callback_), histogram_suffix_));
-
-  if (!task_runner_->PostTask(FROM_HERE, MakeCriticalClosure(task))) {
-    // Posting the task to background message loop is not expected
-    // to fail, but if it does, avoid losing data and just hit the disk
-    // on the current thread.
-    NOTREACHED();
-
-    task.Run();
-  }
-  ClearPendingWrite();
-}
-
-void ImportantFileWriter::ScheduleWrite(DataSerializer* serializer) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  DCHECK(serializer);
-  serializer_ = serializer;
-
-  if (!timer().IsRunning()) {
-    timer().Start(
-        FROM_HERE, commit_interval_,
-        Bind(&ImportantFileWriter::DoScheduledWrite, Unretained(this)));
-  }
-}
-
-void ImportantFileWriter::DoScheduledWrite() {
-  DCHECK(serializer_);
-  std::unique_ptr<std::string> data(new std::string);
-  if (serializer_->SerializeData(data.get())) {
-    WriteNow(std::move(data));
-  } else {
-    DLOG(WARNING) << "failed to serialize data to be saved in "
-                  << path_.value();
-  }
-  ClearPendingWrite();
-}
-
-void ImportantFileWriter::RegisterOnNextWriteCallbacks(
-    const Closure& before_next_write_callback,
-    const Callback<void(bool success)>& after_next_write_callback) {
-  before_next_write_callback_ = before_next_write_callback;
-  after_next_write_callback_ = after_next_write_callback;
-}
-
-void ImportantFileWriter::ClearPendingWrite() {
-  timer().Stop();
-  serializer_ = nullptr;
-}
-
-void ImportantFileWriter::SetTimerForTesting(Timer* timer_override) {
-  timer_override_ = timer_override;
-}
-
-}  // namespace base
diff --git a/base/files/important_file_writer.h b/base/files/important_file_writer.h
deleted file mode 100644
index 08a7ee3..0000000
--- a/base/files/important_file_writer.h
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_FILES_IMPORTANT_FILE_WRITER_H_
-#define BASE_FILES_IMPORTANT_FILE_WRITER_H_
-
-#include <string>
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequence_checker.h"
-#include "base/strings/string_piece.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-
-namespace base {
-
-class SequencedTaskRunner;
-
-// Helper for atomically writing a file to ensure that it won't be corrupted by
-// *application* crash during write (implemented as create, flush, rename).
-//
-// As an added benefit, ImportantFileWriter makes it less likely that the file
-// is corrupted by *system* crash, though even if the ImportantFileWriter call
-// has already returned at the time of the crash it is not specified which
-// version of the file (old or new) is preserved. And depending on system
-// configuration (hardware and software) a significant likelihood of file
-// corruption may remain, thus using ImportantFileWriter is not a valid
-// substitute for file integrity checks and recovery codepaths for malformed
-// files.
-//
-// Also note that ImportantFileWriter can be *really* slow (cf. File::Flush()
-// for details) and thus please don't block shutdown on ImportantFileWriter.
-class BASE_EXPORT ImportantFileWriter {
- public:
-  // Used by ScheduleSave to lazily provide the data to be saved. Allows us
-  // to also batch data serializations.
-  class BASE_EXPORT DataSerializer {
-   public:
-    // Should put serialized string in |data| and return true on successful
-    // serialization. Will be called on the same thread on which
-    // ImportantFileWriter has been created.
-    virtual bool SerializeData(std::string* data) = 0;
-
-   protected:
-    virtual ~DataSerializer() = default;
-  };
-
-  // Save |data| to |path| in an atomic manner. Blocks and writes data on the
-  // current thread. Does not guarantee file integrity across system crash (see
-  // the class comment above).
-  static bool WriteFileAtomically(const FilePath& path,
-                                  StringPiece data,
-                                  StringPiece histogram_suffix = StringPiece());
-
-  // Initialize the writer.
-  // |path| is the name of file to write.
-  // |task_runner| is the SequencedTaskRunner instance where on which we will
-  // execute file I/O operations.
-  // All non-const methods, ctor and dtor must be called on the same thread.
-  ImportantFileWriter(const FilePath& path,
-                      scoped_refptr<SequencedTaskRunner> task_runner,
-                      const char* histogram_suffix = nullptr);
-
-  // Same as above, but with a custom commit interval.
-  ImportantFileWriter(const FilePath& path,
-                      scoped_refptr<SequencedTaskRunner> task_runner,
-                      TimeDelta interval,
-                      const char* histogram_suffix = nullptr);
-
-  // You have to ensure that there are no pending writes at the moment
-  // of destruction.
-  ~ImportantFileWriter();
-
-  const FilePath& path() const { return path_; }
-
-  // Returns true if there is a scheduled write pending which has not yet
-  // been started.
-  bool HasPendingWrite() const;
-
-  // Save |data| to target filename. Does not block. If there is a pending write
-  // scheduled by ScheduleWrite(), it is cancelled.
-  void WriteNow(std::unique_ptr<std::string> data);
-
-  // Schedule a save to target filename. Data will be serialized and saved
-  // to disk after the commit interval. If another ScheduleWrite is issued
-  // before that, only one serialization and write to disk will happen, and
-  // the most recent |serializer| will be used. This operation does not block.
-  // |serializer| should remain valid through the lifetime of
-  // ImportantFileWriter.
-  void ScheduleWrite(DataSerializer* serializer);
-
-  // Serialize data pending to be saved and execute write on backend thread.
-  void DoScheduledWrite();
-
-  // Registers |before_next_write_callback| and |after_next_write_callback| to
-  // be synchronously invoked from WriteFileAtomically() before its next write
-  // and after its next write, respectively. The boolean passed to
-  // |after_next_write_callback| indicates whether the write was successful.
-  // Both callbacks must be thread safe as they will be called on |task_runner_|
-  // and may be called during Chrome shutdown.
-  // If called more than once before a write is scheduled on |task_runner|, the
-  // latest callbacks clobber the others.
-  void RegisterOnNextWriteCallbacks(
-      const Closure& before_next_write_callback,
-      const Callback<void(bool success)>& after_next_write_callback);
-
-  TimeDelta commit_interval() const {
-    return commit_interval_;
-  }
-
-  // Overrides the timer to use for scheduling writes with |timer_override|.
-  void SetTimerForTesting(Timer* timer_override);
-
- private:
-  const Timer& timer() const {
-    return timer_override_ ? const_cast<const Timer&>(*timer_override_)
-                           : timer_;
-  }
-  Timer& timer() { return timer_override_ ? *timer_override_ : timer_; }
-
-  void ClearPendingWrite();
-
-  // Invoked synchronously on the next write event.
-  Closure before_next_write_callback_;
-  Callback<void(bool success)> after_next_write_callback_;
-
-  // Path being written to.
-  const FilePath path_;
-
-  // TaskRunner for the thread on which file I/O can be done.
-  const scoped_refptr<SequencedTaskRunner> task_runner_;
-
-  // Timer used to schedule commit after ScheduleWrite.
-  OneShotTimer timer_;
-
-  // An override for |timer_| used for testing.
-  Timer* timer_override_ = nullptr;
-
-  // Serializer which will provide the data to be saved.
-  DataSerializer* serializer_;
-
-  // Time delta after which scheduled data will be written to disk.
-  const TimeDelta commit_interval_;
-
-  // Custom histogram suffix.
-  const std::string histogram_suffix_;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  WeakPtrFactory<ImportantFileWriter> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(ImportantFileWriter);
-};
-
-}  // namespace base
-
-#endif  // BASE_FILES_IMPORTANT_FILE_WRITER_H_
diff --git a/base/logging.cc b/base/logging.cc
index cf96aeb..72ca87a 100644
--- a/base/logging.cc
+++ b/base/logging.cc
@@ -88,7 +88,6 @@
 #include "base/callback.h"
 #include "base/command_line.h"
 #include "base/containers/stack.h"
-#include "base/debug/activity_tracker.h"
 #include "base/debug/alias.h"
 #include "base/debug/debugger.h"
 #include "base/debug/stack_trace.h"
@@ -816,12 +815,6 @@
   }
 
   if (severity_ == LOG_FATAL) {
-    // Write the log message to the global activity tracker, if running.
-    base::debug::GlobalActivityTracker* tracker =
-        base::debug::GlobalActivityTracker::Get();
-    if (tracker)
-      tracker->RecordLogMessage(str_newline);
-
     // Ensure the first characters of the string are on the stack so they
     // are contained in minidumps for diagnostic purposes.
     DEBUG_ALIAS_FOR_CSTR(str_stack, str_newline.c_str(), 1024);
diff --git a/base/memory/shared_memory_mac.cc b/base/memory/shared_memory_mac.cc
index 3990948..5e9e8fc 100644
--- a/base/memory/shared_memory_mac.cc
+++ b/base/memory/shared_memory_mac.cc
@@ -19,8 +19,6 @@
 #include "base/mac/scoped_mach_vm.h"
 #include "base/memory/shared_memory_helper.h"
 #include "base/memory/shared_memory_tracker.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram_macros.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/posix/safe_strerror.h"
 #include "base/process/process_metrics.h"
diff --git a/base/metrics/OWNERS b/base/metrics/OWNERS
deleted file mode 100644
index 4cc69ff..0000000
--- a/base/metrics/OWNERS
+++ /dev/null
@@ -1,10 +0,0 @@
-asvitkine@chromium.org
-bcwhite@chromium.org
-gayane@chromium.org
-holte@chromium.org
-isherman@chromium.org
-jwd@chromium.org
-mpearson@chromium.org
-rkaplow@chromium.org
-
-# COMPONENT: Internals>Metrics
diff --git a/base/metrics/bucket_ranges.cc b/base/metrics/bucket_ranges.cc
deleted file mode 100644
index 39b3793..0000000
--- a/base/metrics/bucket_ranges.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/bucket_ranges.h"
-
-#include <cmath>
-
-#include "base/logging.h"
-
-namespace base {
-
-// Static table of checksums for all possible 8 bit bytes.
-const uint32_t kCrcTable[256] = {
-    0x0,         0x77073096L, 0xee0e612cL, 0x990951baL, 0x76dc419L,
-    0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0xedb8832L,  0x79dcb8a4L,
-    0xe0d5e91eL, 0x97d2d988L, 0x9b64c2bL,  0x7eb17cbdL, 0xe7b82d07L,
-    0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
-    0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
-    0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
-    0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
-    0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
-    0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
-    0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
-    0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
-    0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
-    0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
-    0x1db7106L,  0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x6b6b51fL,
-    0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0xf00f934L,  0x9609a88eL,
-    0xe10e9818L, 0x7f6a0dbbL, 0x86d3d2dL,  0x91646c97L, 0xe6635c01L,
-    0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
-    0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
-    0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
-    0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
-    0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
-    0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
-    0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
-    0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
-    0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
-    0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
-    0x3b6e20cL,  0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x4db2615L,
-    0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0xd6d6a3eL,  0x7a6a5aa8L,
-    0xe40ecf0bL, 0x9309ff9dL, 0xa00ae27L,  0x7d079eb1L, 0xf00f9344L,
-    0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
-    0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
-    0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
-    0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
-    0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
-    0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
-    0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
-    0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
-    0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
-    0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
-    0x26d930aL,  0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x5005713L,
-    0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0xcb61b38L,  0x92d28e9bL,
-    0xe5d5be0dL, 0x7cdcefb7L, 0xbdbdf21L,  0x86d3d2d4L, 0xf1d4e242L,
-    0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
-    0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
-    0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
-    0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
-    0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
-    0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
-    0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
-    0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
-    0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
-    0x2d02ef8dL,
-};
-
-// We generate the CRC-32 using the low order bits to select whether to XOR in
-// the reversed polynomial 0xedb88320L.  This is nice and simple, and allows us
-// to keep the quotient in a uint32_t.  Since we're not concerned about the
-// nature of corruptions (i.e., we don't care about bit sequencing, since we are
-// handling memory changes, which are more grotesque) so we don't bother to get
-// the CRC correct for big-endian vs little-ending calculations.  All we need is
-// a nice hash, that tends to depend on all the bits of the sample, with very
-// little chance of changes in one place impacting changes in another place.
-static uint32_t Crc32(uint32_t sum, HistogramBase::Sample value) {
-  union {
-    HistogramBase::Sample range;
-    unsigned char bytes[sizeof(HistogramBase::Sample)];
-  } converter;
-  converter.range = value;
-  for (size_t i = 0; i < sizeof(converter); ++i) {
-    sum = kCrcTable[(sum & 0xff) ^ converter.bytes[i]] ^ (sum >> 8);
-  }
-  return sum;
-}
-
-BucketRanges::BucketRanges(size_t num_ranges)
-    : ranges_(num_ranges, 0),
-      checksum_(0) {}
-
-BucketRanges::~BucketRanges() = default;
-
-uint32_t BucketRanges::CalculateChecksum() const {
-  // Seed checksum.
-  uint32_t checksum = static_cast<uint32_t>(ranges_.size());
-
-  for (size_t index = 0; index < ranges_.size(); ++index)
-    checksum = Crc32(checksum, ranges_[index]);
-  return checksum;
-}
-
-bool BucketRanges::HasValidChecksum() const {
-  return CalculateChecksum() == checksum_;
-}
-
-void BucketRanges::ResetChecksum() {
-  checksum_ = CalculateChecksum();
-}
-
-bool BucketRanges::Equals(const BucketRanges* other) const {
-  if (checksum_ != other->checksum_)
-    return false;
-  if (ranges_.size() != other->ranges_.size())
-    return false;
-  for (size_t index = 0; index < ranges_.size(); ++index) {
-    if (ranges_[index] != other->ranges_[index])
-      return false;
-  }
-  return true;
-}
-
-}  // namespace base
diff --git a/base/metrics/bucket_ranges.h b/base/metrics/bucket_ranges.h
deleted file mode 100644
index 1b6d069..0000000
--- a/base/metrics/bucket_ranges.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// BucketRanges stores the vector of ranges that delimit what samples are
-// tallied in the corresponding buckets of a histogram. Histograms that have
-// same ranges for all their corresponding buckets should share the same
-// BucketRanges object.
-//
-// E.g. A 5 buckets LinearHistogram with 1 as minimal value and 4 as maximal
-// value will need a BucketRanges with 6 ranges:
-// 0, 1, 2, 3, 4, INT_MAX
-//
-// TODO(kaiwang): Currently we keep all negative values in 0~1 bucket. Consider
-// changing 0 to INT_MIN.
-
-#ifndef BASE_METRICS_BUCKET_RANGES_H_
-#define BASE_METRICS_BUCKET_RANGES_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <vector>
-
-#include <limits.h>
-
-#include "base/atomicops.h"
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/metrics/histogram_base.h"
-
-namespace base {
-
-class BASE_EXPORT BucketRanges {
- public:
-  typedef std::vector<HistogramBase::Sample> Ranges;
-
-  explicit BucketRanges(size_t num_ranges);
-  ~BucketRanges();
-
-  size_t size() const { return ranges_.size(); }
-  HistogramBase::Sample range(size_t i) const { return ranges_[i]; }
-  void set_range(size_t i, HistogramBase::Sample value) {
-    DCHECK_LT(i, ranges_.size());
-    DCHECK_GE(value, 0);
-    ranges_[i] = value;
-  }
-  uint32_t checksum() const { return checksum_; }
-  void set_checksum(uint32_t checksum) { checksum_ = checksum; }
-
-  // A bucket is defined by a consecutive pair of entries in |ranges|, so there
-  // is one fewer bucket than there are ranges.  For example, if |ranges| is
-  // [0, 1, 3, 7, INT_MAX], then the buckets in this histogram are
-  // [0, 1), [1, 3), [3, 7), and [7, INT_MAX).
-  size_t bucket_count() const { return ranges_.size() - 1; }
-
-  // Checksum methods to verify whether the ranges are corrupted (e.g. bad
-  // memory access).
-  uint32_t CalculateChecksum() const;
-  bool HasValidChecksum() const;
-  void ResetChecksum();
-
-  // Return true iff |other| object has same ranges_ as |this| object's ranges_.
-  bool Equals(const BucketRanges* other) const;
-
-  // Set and get a reference into persistent memory where this bucket data
-  // can be found (and re-used). These calls are internally atomic with no
-  // safety against overwriting an existing value since though it is wasteful
-  // to have multiple identical persistent records, it is still safe.
-  void set_persistent_reference(uint32_t ref) const {
-    subtle::Release_Store(&persistent_reference_, ref);
-  }
-  uint32_t persistent_reference() const {
-    return subtle::Acquire_Load(&persistent_reference_);
-  }
-
- private:
-  // A monotonically increasing list of values which determine which bucket to
-  // put a sample into.  For each index, show the smallest sample that can be
-  // added to the corresponding bucket.
-  Ranges ranges_;
-
-  // Checksum for the conntents of ranges_.  Used to detect random over-writes
-  // of our data, and to quickly see if some other BucketRanges instance is
-  // possibly Equal() to this instance.
-  // TODO(kaiwang): Consider change this to uint64_t. Because we see a lot of
-  // noise on UMA dashboard.
-  uint32_t checksum_;
-
-  // A reference into a global PersistentMemoryAllocator where the ranges
-  // information is stored. This allows for the record to be created once and
-  // re-used simply by having all histograms with the same ranges use the
-  // same reference.
-  mutable subtle::Atomic32 persistent_reference_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(BucketRanges);
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// Expose only for test.
-BASE_EXPORT extern const uint32_t kCrcTable[256];
-
-}  // namespace base
-
-#endif  // BASE_METRICS_BUCKET_RANGES_H_
diff --git a/base/metrics/dummy_histogram.cc b/base/metrics/dummy_histogram.cc
deleted file mode 100644
index 2707733..0000000
--- a/base/metrics/dummy_histogram.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/dummy_histogram.h"
-
-#include <memory>
-
-#include "base/logging.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/metrics_hashes.h"
-
-namespace base {
-
-namespace {
-
-// Helper classes for DummyHistogram.
-class DummySampleCountIterator : public SampleCountIterator {
- public:
-  DummySampleCountIterator() {}
-  ~DummySampleCountIterator() override {}
-
-  // SampleCountIterator:
-  bool Done() const override { return true; }
-  void Next() override { NOTREACHED(); }
-  void Get(HistogramBase::Sample* min,
-           int64_t* max,
-           HistogramBase::Count* count) const override {
-    NOTREACHED();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DummySampleCountIterator);
-};
-
-class DummyHistogramSamples : public HistogramSamples {
- public:
-  explicit DummyHistogramSamples() : HistogramSamples(0, new LocalMetadata()) {}
-  ~DummyHistogramSamples() override {
-    delete static_cast<LocalMetadata*>(meta());
-  }
-
-  // HistogramSamples:
-  void Accumulate(HistogramBase::Sample value,
-                  HistogramBase::Count count) override {}
-  HistogramBase::Count GetCount(HistogramBase::Sample value) const override {
-    return HistogramBase::Count();
-  }
-  HistogramBase::Count TotalCount() const override {
-    return HistogramBase::Count();
-  }
-  std::unique_ptr<SampleCountIterator> Iterator() const override {
-    return std::make_unique<DummySampleCountIterator>();
-  }
-  bool AddSubtractImpl(SampleCountIterator* iter, Operator op) override {
-    return true;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DummyHistogramSamples);
-};
-
-}  // namespace
-
-// static
-DummyHistogram* DummyHistogram::GetInstance() {
-  static base::NoDestructor<DummyHistogram> dummy_histogram;
-  return dummy_histogram.get();
-}
-
-uint64_t DummyHistogram::name_hash() const {
-  return HashMetricName(histogram_name());
-}
-
-HistogramType DummyHistogram::GetHistogramType() const {
-  return DUMMY_HISTOGRAM;
-}
-
-bool DummyHistogram::HasConstructionArguments(
-    Sample expected_minimum,
-    Sample expected_maximum,
-    uint32_t expected_bucket_count) const {
-  return true;
-}
-
-bool DummyHistogram::AddSamplesFromPickle(PickleIterator* iter) {
-  return true;
-}
-
-std::unique_ptr<HistogramSamples> DummyHistogram::SnapshotSamples() const {
-  return std::make_unique<DummyHistogramSamples>();
-}
-
-std::unique_ptr<HistogramSamples> DummyHistogram::SnapshotDelta() {
-  return std::make_unique<DummyHistogramSamples>();
-}
-
-std::unique_ptr<HistogramSamples> DummyHistogram::SnapshotFinalDelta() const {
-  return std::make_unique<DummyHistogramSamples>();
-}
-
-}  // namespace base
diff --git a/base/metrics/dummy_histogram.h b/base/metrics/dummy_histogram.h
deleted file mode 100644
index e2cb64e..0000000
--- a/base/metrics/dummy_histogram.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_DUMMY_HISTOGRAM_H_
-#define BASE_METRICS_DUMMY_HISTOGRAM_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-
-#include "base/base_export.h"
-#include "base/metrics/histogram_base.h"
-#include "base/no_destructor.h"
-
-namespace base {
-
-// DummyHistogram is used for mocking histogram objects for histograms that
-// shouldn't be recorded. It doesn't do any actual processing.
-class BASE_EXPORT DummyHistogram : public HistogramBase {
- public:
-  static DummyHistogram* GetInstance();
-
-  // HistogramBase:
-  void CheckName(const StringPiece& name) const override {}
-  uint64_t name_hash() const override;
-  HistogramType GetHistogramType() const override;
-  bool HasConstructionArguments(Sample expected_minimum,
-                                Sample expected_maximum,
-                                uint32_t expected_bucket_count) const override;
-  void Add(Sample value) override {}
-  void AddCount(Sample value, int count) override {}
-  void AddSamples(const HistogramSamples& samples) override {}
-  bool AddSamplesFromPickle(PickleIterator* iter) override;
-  std::unique_ptr<HistogramSamples> SnapshotSamples() const override;
-  std::unique_ptr<HistogramSamples> SnapshotDelta() override;
-  std::unique_ptr<HistogramSamples> SnapshotFinalDelta() const override;
-  void WriteHTMLGraph(std::string* output) const override {}
-  void WriteAscii(std::string* output) const override {}
-
- protected:
-  // HistogramBase:
-  void SerializeInfoImpl(Pickle* pickle) const override {}
-  void GetParameters(DictionaryValue* params) const override {}
-  void GetCountAndBucketData(Count* count,
-                             int64_t* sum,
-                             ListValue* buckets) const override {}
-
- private:
-  friend class NoDestructor<DummyHistogram>;
-
-  DummyHistogram() : HistogramBase("dummy_histogram") {}
-  ~DummyHistogram() override {}
-
-  DISALLOW_COPY_AND_ASSIGN(DummyHistogram);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_DUMMY_HISTOGRAM_H_
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc
deleted file mode 100644
index 25f21ca..0000000
--- a/base/metrics/field_trial.cc
+++ /dev/null
@@ -1,1517 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/field_trial.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "base/base_switches.h"
-#include "base/command_line.h"
-#include "base/debug/activity_tracker.h"
-#include "base/logging.h"
-#include "base/metrics/field_trial_param_associator.h"
-#include "base/process/memory.h"
-#include "base/process/process_handle.h"
-#include "base/process/process_info.h"
-#include "base/rand_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/unguessable_token.h"
-
-// On POSIX, the fd is shared using the mapping in GlobalDescriptors.
-#if defined(OS_POSIX) && !defined(OS_NACL)
-#include "base/posix/global_descriptors.h"
-#endif
-
-namespace base {
-
-namespace {
-
-// Define a separator character to use when creating a persistent form of an
-// instance.  This is intended for use as a command line argument, passed to a
-// second process to mimic our state (i.e., provide the same group name).
-const char kPersistentStringSeparator = '/';  // Currently a slash.
-
-// Define a marker character to be used as a prefix to a trial name on the
-// command line which forces its activation.
-const char kActivationMarker = '*';
-
-// Use shared memory to communicate field trial (experiment) state. Set to false
-// for now while the implementation is fleshed out (e.g. data format, single
-// shared memory segment). See https://codereview.chromium.org/2365273004/ and
-// crbug.com/653874
-// The browser is the only process that has write access to the shared memory.
-// This is safe from race conditions because MakeIterable is a release operation
-// and GetNextOfType is an acquire operation, so memory writes before
-// MakeIterable happen before memory reads after GetNextOfType.
-#if defined(OS_FUCHSIA)  // TODO(752368): Not yet supported on Fuchsia.
-const bool kUseSharedMemoryForFieldTrials = false;
-#else
-const bool kUseSharedMemoryForFieldTrials = true;
-#endif
-
-// Constants for the field trial allocator.
-const char kAllocatorName[] = "FieldTrialAllocator";
-
-// We allocate 128 KiB to hold all the field trial data. This should be enough,
-// as most people use 3 - 25 KiB for field trials (as of 11/25/2016).
-// This also doesn't allocate all 128 KiB at once -- the pages only get mapped
-// to physical memory when they are touched. If the size of the allocated field
-// trials does get larger than 128 KiB, then we will drop some field trials in
-// child processes, leading to an inconsistent view between browser and child
-// processes and possibly causing crashes (see crbug.com/661617).
-const size_t kFieldTrialAllocationSize = 128 << 10;  // 128 KiB
-
-// Writes out string1 and then string2 to pickle.
-void WriteStringPair(Pickle* pickle,
-                     const StringPiece& string1,
-                     const StringPiece& string2) {
-  pickle->WriteString(string1);
-  pickle->WriteString(string2);
-}
-
-// Writes out the field trial's contents (via trial_state) to the pickle. The
-// format of the pickle looks like:
-// TrialName, GroupName, ParamKey1, ParamValue1, ParamKey2, ParamValue2, ...
-// If there are no parameters, then it just ends at GroupName.
-void PickleFieldTrial(const FieldTrial::State& trial_state, Pickle* pickle) {
-  WriteStringPair(pickle, *trial_state.trial_name, *trial_state.group_name);
-
-  // Get field trial params.
-  std::map<std::string, std::string> params;
-  FieldTrialParamAssociator::GetInstance()->GetFieldTrialParamsWithoutFallback(
-      *trial_state.trial_name, *trial_state.group_name, &params);
-
-  // Write params to pickle.
-  for (const auto& param : params)
-    WriteStringPair(pickle, param.first, param.second);
-}
-
-// Created a time value based on |year|, |month| and |day_of_month| parameters.
-Time CreateTimeFromParams(int year, int month, int day_of_month) {
-  DCHECK_GT(year, 1970);
-  DCHECK_GT(month, 0);
-  DCHECK_LT(month, 13);
-  DCHECK_GT(day_of_month, 0);
-  DCHECK_LT(day_of_month, 32);
-
-  Time::Exploded exploded;
-  exploded.year = year;
-  exploded.month = month;
-  exploded.day_of_week = 0;  // Should be unused.
-  exploded.day_of_month = day_of_month;
-  exploded.hour = 0;
-  exploded.minute = 0;
-  exploded.second = 0;
-  exploded.millisecond = 0;
-  Time out_time;
-  if (!Time::FromLocalExploded(exploded, &out_time)) {
-    // TODO(maksims): implement failure handling.
-    // We might just return |out_time|, which is Time(0).
-    NOTIMPLEMENTED();
-  }
-
-  return out_time;
-}
-
-// Returns the boundary value for comparing against the FieldTrial's added
-// groups for a given |divisor| (total probability) and |entropy_value|.
-FieldTrial::Probability GetGroupBoundaryValue(
-    FieldTrial::Probability divisor,
-    double entropy_value) {
-  // Add a tiny epsilon value to get consistent results when converting floating
-  // points to int. Without it, boundary values have inconsistent results, e.g.:
-  //
-  //   static_cast<FieldTrial::Probability>(100 * 0.56) == 56
-  //   static_cast<FieldTrial::Probability>(100 * 0.57) == 56
-  //   static_cast<FieldTrial::Probability>(100 * 0.58) == 57
-  //   static_cast<FieldTrial::Probability>(100 * 0.59) == 59
-  const double kEpsilon = 1e-8;
-  const FieldTrial::Probability result =
-      static_cast<FieldTrial::Probability>(divisor * entropy_value + kEpsilon);
-  // Ensure that adding the epsilon still results in a value < |divisor|.
-  return std::min(result, divisor - 1);
-}
-
-// Separate type from FieldTrial::State so that it can use StringPieces.
-struct FieldTrialStringEntry {
-  StringPiece trial_name;
-  StringPiece group_name;
-  bool activated = false;
-};
-
-// Parses the --force-fieldtrials string |trials_string| into |entries|.
-// Returns true if the string was parsed correctly. On failure, the |entries|
-// array may end up being partially filled.
-bool ParseFieldTrialsString(const std::string& trials_string,
-                            std::vector<FieldTrialStringEntry>* entries) {
-  const StringPiece trials_string_piece(trials_string);
-
-  size_t next_item = 0;
-  while (next_item < trials_string.length()) {
-    size_t name_end = trials_string.find(kPersistentStringSeparator, next_item);
-    if (name_end == trials_string.npos || next_item == name_end)
-      return false;
-    size_t group_name_end =
-        trials_string.find(kPersistentStringSeparator, name_end + 1);
-    if (name_end + 1 == group_name_end)
-      return false;
-    if (group_name_end == trials_string.npos)
-      group_name_end = trials_string.length();
-
-    FieldTrialStringEntry entry;
-    // Verify if the trial should be activated or not.
-    if (trials_string[next_item] == kActivationMarker) {
-      // Name cannot be only the indicator.
-      if (name_end - next_item == 1)
-        return false;
-      next_item++;
-      entry.activated = true;
-    }
-    entry.trial_name =
-        trials_string_piece.substr(next_item, name_end - next_item);
-    entry.group_name =
-        trials_string_piece.substr(name_end + 1, group_name_end - name_end - 1);
-    next_item = group_name_end + 1;
-
-    entries->push_back(std::move(entry));
-  }
-  return true;
-}
-
-void AddFeatureAndFieldTrialFlags(const char* enable_features_switch,
-                                  const char* disable_features_switch,
-                                  CommandLine* cmd_line) {
-  std::string enabled_features;
-  std::string disabled_features;
-  FeatureList::GetInstance()->GetFeatureOverrides(&enabled_features,
-                                                  &disabled_features);
-
-  if (!enabled_features.empty())
-    cmd_line->AppendSwitchASCII(enable_features_switch, enabled_features);
-  if (!disabled_features.empty())
-    cmd_line->AppendSwitchASCII(disable_features_switch, disabled_features);
-
-  std::string field_trial_states;
-  FieldTrialList::AllStatesToString(&field_trial_states, false);
-  if (!field_trial_states.empty()) {
-    cmd_line->AppendSwitchASCII(switches::kForceFieldTrials,
-                                field_trial_states);
-  }
-}
-
-void OnOutOfMemory(size_t size) {
-#if defined(OS_NACL)
-  NOTREACHED();
-#else
-  TerminateBecauseOutOfMemory(size);
-#endif
-}
-
-#if !defined(OS_NACL)
-// Returns whether the operation succeeded.
-bool DeserializeGUIDFromStringPieces(base::StringPiece first,
-                                     base::StringPiece second,
-                                     base::UnguessableToken* guid) {
-  uint64_t high = 0;
-  uint64_t low = 0;
-  if (!base::StringToUint64(first, &high) ||
-      !base::StringToUint64(second, &low)) {
-    return false;
-  }
-
-  *guid = base::UnguessableToken::Deserialize(high, low);
-  return true;
-}
-
-// Extract a read-only SharedMemoryHandle from an existing |shared_memory|
-// handle. Note that on Android, this also makes the whole region read-only.
-SharedMemoryHandle GetSharedMemoryReadOnlyHandle(SharedMemory* shared_memory) {
-  SharedMemoryHandle result = shared_memory->GetReadOnlyHandle();
-#if defined(OS_ANDROID)
-  // On Android, turn the region read-only. This prevents any future
-  // writable mapping attempts, but the original one in |shm| survives
-  // and is still usable in the current process.
-  result.SetRegionReadOnly();
-#endif  // OS_ANDROID
-  return result;
-}
-#endif  // !OS_NACL
-
-}  // namespace
-
-// statics
-const int FieldTrial::kNotFinalized = -1;
-const int FieldTrial::kDefaultGroupNumber = 0;
-bool FieldTrial::enable_benchmarking_ = false;
-
-int FieldTrialList::kNoExpirationYear = 0;
-
-//------------------------------------------------------------------------------
-// FieldTrial methods and members.
-
-FieldTrial::EntropyProvider::~EntropyProvider() = default;
-
-FieldTrial::State::State() = default;
-
-FieldTrial::State::State(const State& other) = default;
-
-FieldTrial::State::~State() = default;
-
-bool FieldTrial::FieldTrialEntry::GetTrialAndGroupName(
-    StringPiece* trial_name,
-    StringPiece* group_name) const {
-  PickleIterator iter = GetPickleIterator();
-  return ReadStringPair(&iter, trial_name, group_name);
-}
-
-bool FieldTrial::FieldTrialEntry::GetParams(
-    std::map<std::string, std::string>* params) const {
-  PickleIterator iter = GetPickleIterator();
-  StringPiece tmp;
-  // Skip reading trial and group name.
-  if (!ReadStringPair(&iter, &tmp, &tmp))
-    return false;
-
-  while (true) {
-    StringPiece key;
-    StringPiece value;
-    if (!ReadStringPair(&iter, &key, &value))
-      return key.empty();  // Non-empty is bad: got one of a pair.
-    (*params)[key.as_string()] = value.as_string();
-  }
-}
-
-PickleIterator FieldTrial::FieldTrialEntry::GetPickleIterator() const {
-  const char* src =
-      reinterpret_cast<const char*>(this) + sizeof(FieldTrialEntry);
-
-  Pickle pickle(src, pickle_size);
-  return PickleIterator(pickle);
-}
-
-bool FieldTrial::FieldTrialEntry::ReadStringPair(
-    PickleIterator* iter,
-    StringPiece* trial_name,
-    StringPiece* group_name) const {
-  if (!iter->ReadStringPiece(trial_name))
-    return false;
-  if (!iter->ReadStringPiece(group_name))
-    return false;
-  return true;
-}
-
-void FieldTrial::Disable() {
-  DCHECK(!group_reported_);
-  enable_field_trial_ = false;
-
-  // In case we are disabled after initialization, we need to switch
-  // the trial to the default group.
-  if (group_ != kNotFinalized) {
-    // Only reset when not already the default group, because in case we were
-    // forced to the default group, the group number may not be
-    // kDefaultGroupNumber, so we should keep it as is.
-    if (group_name_ != default_group_name_)
-      SetGroupChoice(default_group_name_, kDefaultGroupNumber);
-  }
-}
-
-int FieldTrial::AppendGroup(const std::string& name,
-                            Probability group_probability) {
-  // When the group choice was previously forced, we only need to return the
-  // the id of the chosen group, and anything can be returned for the others.
-  if (forced_) {
-    DCHECK(!group_name_.empty());
-    if (name == group_name_) {
-      // Note that while |group_| may be equal to |kDefaultGroupNumber| on the
-      // forced trial, it will not have the same value as the default group
-      // number returned from the non-forced |FactoryGetFieldTrial()| call,
-      // which takes care to ensure that this does not happen.
-      return group_;
-    }
-    DCHECK_NE(next_group_number_, group_);
-    // We still return different numbers each time, in case some caller need
-    // them to be different.
-    return next_group_number_++;
-  }
-
-  DCHECK_LE(group_probability, divisor_);
-  DCHECK_GE(group_probability, 0);
-
-  if (enable_benchmarking_ || !enable_field_trial_)
-    group_probability = 0;
-
-  accumulated_group_probability_ += group_probability;
-
-  DCHECK_LE(accumulated_group_probability_, divisor_);
-  if (group_ == kNotFinalized && accumulated_group_probability_ > random_) {
-    // This is the group that crossed the random line, so we do the assignment.
-    SetGroupChoice(name, next_group_number_);
-  }
-  return next_group_number_++;
-}
-
-int FieldTrial::group() {
-  FinalizeGroupChoice();
-  if (trial_registered_)
-    FieldTrialList::NotifyFieldTrialGroupSelection(this);
-  return group_;
-}
-
-const std::string& FieldTrial::group_name() {
-  // Call |group()| to ensure group gets assigned and observers are notified.
-  group();
-  DCHECK(!group_name_.empty());
-  return group_name_;
-}
-
-const std::string& FieldTrial::GetGroupNameWithoutActivation() {
-  FinalizeGroupChoice();
-  return group_name_;
-}
-
-void FieldTrial::SetForced() {
-  // We might have been forced before (e.g., by CreateFieldTrial) and it's
-  // first come first served, e.g., command line switch has precedence.
-  if (forced_)
-    return;
-
-  // And we must finalize the group choice before we mark ourselves as forced.
-  FinalizeGroupChoice();
-  forced_ = true;
-}
-
-// static
-void FieldTrial::EnableBenchmarking() {
-  DCHECK_EQ(0u, FieldTrialList::GetFieldTrialCount());
-  enable_benchmarking_ = true;
-}
-
-// static
-FieldTrial* FieldTrial::CreateSimulatedFieldTrial(
-    const std::string& trial_name,
-    Probability total_probability,
-    const std::string& default_group_name,
-    double entropy_value) {
-  return new FieldTrial(trial_name, total_probability, default_group_name,
-                        entropy_value);
-}
-
-FieldTrial::FieldTrial(const std::string& trial_name,
-                       const Probability total_probability,
-                       const std::string& default_group_name,
-                       double entropy_value)
-    : trial_name_(trial_name),
-      divisor_(total_probability),
-      default_group_name_(default_group_name),
-      random_(GetGroupBoundaryValue(total_probability, entropy_value)),
-      accumulated_group_probability_(0),
-      next_group_number_(kDefaultGroupNumber + 1),
-      group_(kNotFinalized),
-      enable_field_trial_(true),
-      forced_(false),
-      group_reported_(false),
-      trial_registered_(false),
-      ref_(FieldTrialList::FieldTrialAllocator::kReferenceNull) {
-  DCHECK_GT(total_probability, 0);
-  DCHECK(!trial_name_.empty());
-  DCHECK(!default_group_name_.empty())
-      << "Trial " << trial_name << " is missing a default group name.";
-}
-
-FieldTrial::~FieldTrial() = default;
-
-void FieldTrial::SetTrialRegistered() {
-  DCHECK_EQ(kNotFinalized, group_);
-  DCHECK(!trial_registered_);
-  trial_registered_ = true;
-}
-
-void FieldTrial::SetGroupChoice(const std::string& group_name, int number) {
-  group_ = number;
-  if (group_name.empty())
-    StringAppendF(&group_name_, "%d", group_);
-  else
-    group_name_ = group_name;
-  DVLOG(1) << "Field trial: " << trial_name_ << " Group choice:" << group_name_;
-}
-
-void FieldTrial::FinalizeGroupChoice() {
-  FinalizeGroupChoiceImpl(false);
-}
-
-void FieldTrial::FinalizeGroupChoiceImpl(bool is_locked) {
-  if (group_ != kNotFinalized)
-    return;
-  accumulated_group_probability_ = divisor_;
-  // Here it's OK to use |kDefaultGroupNumber| since we can't be forced and not
-  // finalized.
-  DCHECK(!forced_);
-  SetGroupChoice(default_group_name_, kDefaultGroupNumber);
-
-  // Add the field trial to shared memory.
-  if (kUseSharedMemoryForFieldTrials && trial_registered_)
-    FieldTrialList::OnGroupFinalized(is_locked, this);
-}
-
-bool FieldTrial::GetActiveGroup(ActiveGroup* active_group) const {
-  if (!group_reported_ || !enable_field_trial_)
-    return false;
-  DCHECK_NE(group_, kNotFinalized);
-  active_group->trial_name = trial_name_;
-  active_group->group_name = group_name_;
-  return true;
-}
-
-bool FieldTrial::GetStateWhileLocked(State* field_trial_state,
-                                     bool include_expired) {
-  if (!include_expired && !enable_field_trial_)
-    return false;
-  FinalizeGroupChoiceImpl(true);
-  field_trial_state->trial_name = &trial_name_;
-  field_trial_state->group_name = &group_name_;
-  field_trial_state->activated = group_reported_;
-  return true;
-}
-
-//------------------------------------------------------------------------------
-// FieldTrialList methods and members.
-
-// static
-FieldTrialList* FieldTrialList::global_ = nullptr;
-
-// static
-bool FieldTrialList::used_without_global_ = false;
-
-FieldTrialList::Observer::~Observer() = default;
-
-FieldTrialList::FieldTrialList(
-    std::unique_ptr<const FieldTrial::EntropyProvider> entropy_provider)
-    : entropy_provider_(std::move(entropy_provider)),
-      observer_list_(new ObserverListThreadSafe<FieldTrialList::Observer>(
-          ObserverListPolicy::EXISTING_ONLY)) {
-  DCHECK(!global_);
-  DCHECK(!used_without_global_);
-  global_ = this;
-
-  CHECK(false);  // TODO(scottmg): Remove FieldTrialList.
-}
-
-FieldTrialList::~FieldTrialList() {
-  AutoLock auto_lock(lock_);
-  while (!registered_.empty()) {
-    RegistrationMap::iterator it = registered_.begin();
-    it->second->Release();
-    registered_.erase(it->first);
-  }
-  DCHECK_EQ(this, global_);
-  global_ = nullptr;
-}
-
-// static
-FieldTrial* FieldTrialList::FactoryGetFieldTrial(
-    const std::string& trial_name,
-    FieldTrial::Probability total_probability,
-    const std::string& default_group_name,
-    const int year,
-    const int month,
-    const int day_of_month,
-    FieldTrial::RandomizationType randomization_type,
-    int* default_group_number) {
-  return FactoryGetFieldTrialWithRandomizationSeed(
-      trial_name, total_probability, default_group_name, year, month,
-      day_of_month, randomization_type, 0, default_group_number, nullptr);
-}
-
-// static
-FieldTrial* FieldTrialList::FactoryGetFieldTrialWithRandomizationSeed(
-    const std::string& trial_name,
-    FieldTrial::Probability total_probability,
-    const std::string& default_group_name,
-    const int year,
-    const int month,
-    const int day_of_month,
-    FieldTrial::RandomizationType randomization_type,
-    uint32_t randomization_seed,
-    int* default_group_number,
-    const FieldTrial::EntropyProvider* override_entropy_provider) {
-  if (default_group_number)
-    *default_group_number = FieldTrial::kDefaultGroupNumber;
-  // Check if the field trial has already been created in some other way.
-  FieldTrial* existing_trial = Find(trial_name);
-  if (existing_trial) {
-    CHECK(existing_trial->forced_);
-    // If the default group name differs between the existing forced trial
-    // and this trial, then use a different value for the default group number.
-    if (default_group_number &&
-        default_group_name != existing_trial->default_group_name()) {
-      // If the new default group number corresponds to the group that was
-      // chosen for the forced trial (which has been finalized when it was
-      // forced), then set the default group number to that.
-      if (default_group_name == existing_trial->group_name_internal()) {
-        *default_group_number = existing_trial->group_;
-      } else {
-        // Otherwise, use |kNonConflictingGroupNumber| (-2) for the default
-        // group number, so that it does not conflict with the |AppendGroup()|
-        // result for the chosen group.
-        const int kNonConflictingGroupNumber = -2;
-        static_assert(
-            kNonConflictingGroupNumber != FieldTrial::kDefaultGroupNumber,
-            "The 'non-conflicting' group number conflicts");
-        static_assert(kNonConflictingGroupNumber != FieldTrial::kNotFinalized,
-                      "The 'non-conflicting' group number conflicts");
-        *default_group_number = kNonConflictingGroupNumber;
-      }
-    }
-    return existing_trial;
-  }
-
-  double entropy_value;
-  if (randomization_type == FieldTrial::ONE_TIME_RANDOMIZED) {
-    // If an override entropy provider is given, use it.
-    const FieldTrial::EntropyProvider* entropy_provider =
-        override_entropy_provider ? override_entropy_provider
-                                  : GetEntropyProviderForOneTimeRandomization();
-    CHECK(entropy_provider);
-    entropy_value = entropy_provider->GetEntropyForTrial(trial_name,
-                                                         randomization_seed);
-  } else {
-    DCHECK_EQ(FieldTrial::SESSION_RANDOMIZED, randomization_type);
-    DCHECK_EQ(0U, randomization_seed);
-    entropy_value = RandDouble();
-  }
-
-  FieldTrial* field_trial = new FieldTrial(trial_name, total_probability,
-                                           default_group_name, entropy_value);
-  CHECK(false);  // TODO(scottmg): Remove FieldTrialList.
-  return field_trial;
-}
-
-// static
-FieldTrial* FieldTrialList::Find(const std::string& trial_name) {
-  if (!global_)
-    return nullptr;
-  AutoLock auto_lock(global_->lock_);
-  return global_->PreLockedFind(trial_name);
-}
-
-// static
-int FieldTrialList::FindValue(const std::string& trial_name) {
-  FieldTrial* field_trial = Find(trial_name);
-  if (field_trial)
-    return field_trial->group();
-  return FieldTrial::kNotFinalized;
-}
-
-// static
-std::string FieldTrialList::FindFullName(const std::string& trial_name) {
-  FieldTrial* field_trial = Find(trial_name);
-  if (field_trial)
-    return field_trial->group_name();
-  return std::string();
-}
-
-// static
-bool FieldTrialList::TrialExists(const std::string& trial_name) {
-  return Find(trial_name) != nullptr;
-}
-
-// static
-bool FieldTrialList::IsTrialActive(const std::string& trial_name) {
-  FieldTrial* field_trial = Find(trial_name);
-  FieldTrial::ActiveGroup active_group;
-  return field_trial && field_trial->GetActiveGroup(&active_group);
-}
-
-// static
-void FieldTrialList::StatesToString(std::string* output) {
-  FieldTrial::ActiveGroups active_groups;
-  GetActiveFieldTrialGroups(&active_groups);
-  for (FieldTrial::ActiveGroups::const_iterator it = active_groups.begin();
-       it != active_groups.end(); ++it) {
-    DCHECK_EQ(std::string::npos,
-              it->trial_name.find(kPersistentStringSeparator));
-    DCHECK_EQ(std::string::npos,
-              it->group_name.find(kPersistentStringSeparator));
-    output->append(it->trial_name);
-    output->append(1, kPersistentStringSeparator);
-    output->append(it->group_name);
-    output->append(1, kPersistentStringSeparator);
-  }
-}
-
-// static
-void FieldTrialList::AllStatesToString(std::string* output,
-                                       bool include_expired) {
-  if (!global_)
-    return;
-  AutoLock auto_lock(global_->lock_);
-
-  for (const auto& registered : global_->registered_) {
-    FieldTrial::State trial;
-    if (!registered.second->GetStateWhileLocked(&trial, include_expired))
-      continue;
-    DCHECK_EQ(std::string::npos,
-              trial.trial_name->find(kPersistentStringSeparator));
-    DCHECK_EQ(std::string::npos,
-              trial.group_name->find(kPersistentStringSeparator));
-    if (trial.activated)
-      output->append(1, kActivationMarker);
-    output->append(*trial.trial_name);
-    output->append(1, kPersistentStringSeparator);
-    output->append(*trial.group_name);
-    output->append(1, kPersistentStringSeparator);
-  }
-}
-
-// static
-std::string FieldTrialList::AllParamsToString(bool include_expired,
-                                              EscapeDataFunc encode_data_func) {
-  FieldTrialParamAssociator* params_associator =
-      FieldTrialParamAssociator::GetInstance();
-  std::string output;
-  for (const auto& registered : GetRegisteredTrials()) {
-    FieldTrial::State trial;
-    if (!registered.second->GetStateWhileLocked(&trial, include_expired))
-      continue;
-    DCHECK_EQ(std::string::npos,
-              trial.trial_name->find(kPersistentStringSeparator));
-    DCHECK_EQ(std::string::npos,
-              trial.group_name->find(kPersistentStringSeparator));
-    std::map<std::string, std::string> params;
-    if (params_associator->GetFieldTrialParamsWithoutFallback(
-            *trial.trial_name, *trial.group_name, &params)) {
-      if (params.size() > 0) {
-        // Add comma to seprate from previous entry if it exists.
-        if (!output.empty())
-          output.append(1, ',');
-
-        output.append(encode_data_func(*trial.trial_name));
-        output.append(1, '.');
-        output.append(encode_data_func(*trial.group_name));
-        output.append(1, ':');
-
-        std::string param_str;
-        for (const auto& param : params) {
-          // Add separator from previous param information if it exists.
-          if (!param_str.empty())
-            param_str.append(1, kPersistentStringSeparator);
-          param_str.append(encode_data_func(param.first));
-          param_str.append(1, kPersistentStringSeparator);
-          param_str.append(encode_data_func(param.second));
-        }
-
-        output.append(param_str);
-      }
-    }
-  }
-  return output;
-}
-
-// static
-void FieldTrialList::GetActiveFieldTrialGroups(
-    FieldTrial::ActiveGroups* active_groups) {
-  DCHECK(active_groups->empty());
-  if (!global_)
-    return;
-  AutoLock auto_lock(global_->lock_);
-
-  for (RegistrationMap::iterator it = global_->registered_.begin();
-       it != global_->registered_.end(); ++it) {
-    FieldTrial::ActiveGroup active_group;
-    if (it->second->GetActiveGroup(&active_group))
-      active_groups->push_back(active_group);
-  }
-}
-
-// static
-void FieldTrialList::GetActiveFieldTrialGroupsFromString(
-    const std::string& trials_string,
-    FieldTrial::ActiveGroups* active_groups) {
-  std::vector<FieldTrialStringEntry> entries;
-  if (!ParseFieldTrialsString(trials_string, &entries))
-    return;
-
-  for (const auto& entry : entries) {
-    if (entry.activated) {
-      FieldTrial::ActiveGroup group;
-      group.trial_name = entry.trial_name.as_string();
-      group.group_name = entry.group_name.as_string();
-      active_groups->push_back(group);
-    }
-  }
-}
-
-// static
-void FieldTrialList::GetInitiallyActiveFieldTrials(
-    const base::CommandLine& command_line,
-    FieldTrial::ActiveGroups* active_groups) {
-  DCHECK(global_);
-  DCHECK(global_->create_trials_from_command_line_called_);
-
-  if (!global_->field_trial_allocator_) {
-    GetActiveFieldTrialGroupsFromString(
-        command_line.GetSwitchValueASCII(switches::kForceFieldTrials),
-        active_groups);
-    return;
-  }
-
-  FieldTrialAllocator* allocator = global_->field_trial_allocator_.get();
-  FieldTrialAllocator::Iterator mem_iter(allocator);
-  const FieldTrial::FieldTrialEntry* entry;
-  while ((entry = mem_iter.GetNextOfObject<FieldTrial::FieldTrialEntry>()) !=
-         nullptr) {
-    StringPiece trial_name;
-    StringPiece group_name;
-    if (subtle::NoBarrier_Load(&entry->activated) &&
-        entry->GetTrialAndGroupName(&trial_name, &group_name)) {
-      FieldTrial::ActiveGroup group;
-      group.trial_name = trial_name.as_string();
-      group.group_name = group_name.as_string();
-      active_groups->push_back(group);
-    }
-  }
-}
-
-// static
-bool FieldTrialList::CreateTrialsFromString(
-    const std::string& trials_string,
-    const std::set<std::string>& ignored_trial_names) {
-  DCHECK(global_);
-  if (trials_string.empty() || !global_)
-    return true;
-
-  std::vector<FieldTrialStringEntry> entries;
-  if (!ParseFieldTrialsString(trials_string, &entries))
-    return false;
-
-  for (const auto& entry : entries) {
-    const std::string trial_name = entry.trial_name.as_string();
-    const std::string group_name = entry.group_name.as_string();
-
-    if (ContainsKey(ignored_trial_names, trial_name)) {
-      // This is to warn that the field trial forced through command-line
-      // input is unforcable.
-      // Use --enable-logging or --enable-logging=stderr to see this warning.
-      LOG(WARNING) << "Field trial: " << trial_name << " cannot be forced.";
-      continue;
-    }
-
-    FieldTrial* trial = CreateFieldTrial(trial_name, group_name);
-    if (!trial)
-      return false;
-    if (entry.activated) {
-      // Call |group()| to mark the trial as "used" and notify observers, if
-      // any. This is useful to ensure that field trials created in child
-      // processes are properly reported in crash reports.
-      trial->group();
-    }
-  }
-  return true;
-}
-
-// static
-void FieldTrialList::CreateTrialsFromCommandLine(
-    const CommandLine& cmd_line,
-    const char* field_trial_handle_switch,
-    int fd_key) {
-  global_->create_trials_from_command_line_called_ = true;
-
-#if defined(OS_WIN) || defined(OS_FUCHSIA)
-  if (cmd_line.HasSwitch(field_trial_handle_switch)) {
-    std::string switch_value =
-        cmd_line.GetSwitchValueASCII(field_trial_handle_switch);
-    bool result = CreateTrialsFromSwitchValue(switch_value);
-    DCHECK(result);
-  }
-#elif defined(OS_POSIX) && !defined(OS_NACL)
-  // On POSIX, we check if the handle is valid by seeing if the browser process
-  // sent over the switch (we don't care about the value). Invalid handles
-  // occur in some browser tests which don't initialize the allocator.
-  if (cmd_line.HasSwitch(field_trial_handle_switch)) {
-    std::string switch_value =
-        cmd_line.GetSwitchValueASCII(field_trial_handle_switch);
-    bool result = CreateTrialsFromDescriptor(fd_key, switch_value);
-    DCHECK(result);
-  }
-#endif
-
-  if (cmd_line.HasSwitch(switches::kForceFieldTrials)) {
-    bool result = FieldTrialList::CreateTrialsFromString(
-        cmd_line.GetSwitchValueASCII(switches::kForceFieldTrials),
-        std::set<std::string>());
-    DCHECK(result);
-  }
-}
-
-// static
-void FieldTrialList::CreateFeaturesFromCommandLine(
-    const base::CommandLine& command_line,
-    const char* enable_features_switch,
-    const char* disable_features_switch,
-    FeatureList* feature_list) {
-  // Fallback to command line if not using shared memory.
-  if (!kUseSharedMemoryForFieldTrials ||
-      !global_->field_trial_allocator_.get()) {
-    return feature_list->InitializeFromCommandLine(
-        command_line.GetSwitchValueASCII(enable_features_switch),
-        command_line.GetSwitchValueASCII(disable_features_switch));
-  }
-
-  feature_list->InitializeFromSharedMemory(
-      global_->field_trial_allocator_.get());
-}
-
-#if defined(OS_WIN)
-// static
-void FieldTrialList::AppendFieldTrialHandleIfNeeded(
-    HandlesToInheritVector* handles) {
-  if (!global_)
-    return;
-  if (kUseSharedMemoryForFieldTrials) {
-    InstantiateFieldTrialAllocatorIfNeeded();
-    if (global_->readonly_allocator_handle_.IsValid())
-      handles->push_back(global_->readonly_allocator_handle_.GetHandle());
-  }
-}
-#elif defined(OS_FUCHSIA)
-// TODO(fuchsia): Implement shared-memory configuration (crbug.com/752368).
-#elif defined(OS_POSIX) && !defined(OS_NACL)
-// static
-SharedMemoryHandle FieldTrialList::GetFieldTrialHandle() {
-  if (global_ && kUseSharedMemoryForFieldTrials) {
-    InstantiateFieldTrialAllocatorIfNeeded();
-    // We check for an invalid handle where this gets called.
-    return global_->readonly_allocator_handle_;
-  }
-  return SharedMemoryHandle();
-}
-#endif
-
-// static
-void FieldTrialList::CopyFieldTrialStateToFlags(
-    const char* field_trial_handle_switch,
-    const char* enable_features_switch,
-    const char* disable_features_switch,
-    CommandLine* cmd_line) {
-  // TODO(lawrencewu): Ideally, having the global would be guaranteed. However,
-  // content browser tests currently don't create a FieldTrialList because they
-  // don't run ChromeBrowserMainParts code where it's done for Chrome.
-  // Some tests depend on the enable and disable features flag switch, though,
-  // so we can still add those even though AllStatesToString() will be a no-op.
-  if (!global_) {
-    AddFeatureAndFieldTrialFlags(enable_features_switch,
-                                 disable_features_switch, cmd_line);
-    return;
-  }
-
-  // Use shared memory to pass the state if the feature is enabled, otherwise
-  // fallback to passing it via the command line as a string.
-  if (kUseSharedMemoryForFieldTrials) {
-    InstantiateFieldTrialAllocatorIfNeeded();
-    // If the readonly handle didn't get duplicated properly, then fallback to
-    // original behavior.
-    if (!global_->readonly_allocator_handle_.IsValid()) {
-      AddFeatureAndFieldTrialFlags(enable_features_switch,
-                                   disable_features_switch, cmd_line);
-      return;
-    }
-
-    global_->field_trial_allocator_->UpdateTrackingHistograms();
-    std::string switch_value = SerializeSharedMemoryHandleMetadata(
-        global_->readonly_allocator_handle_);
-    cmd_line->AppendSwitchASCII(field_trial_handle_switch, switch_value);
-
-    // Append --enable-features and --disable-features switches corresponding
-    // to the features enabled on the command-line, so that child and browser
-    // process command lines match and clearly show what has been specified
-    // explicitly by the user.
-    std::string enabled_features;
-    std::string disabled_features;
-    FeatureList::GetInstance()->GetCommandLineFeatureOverrides(
-        &enabled_features, &disabled_features);
-
-    if (!enabled_features.empty())
-      cmd_line->AppendSwitchASCII(enable_features_switch, enabled_features);
-    if (!disabled_features.empty())
-      cmd_line->AppendSwitchASCII(disable_features_switch, disabled_features);
-
-    return;
-  }
-
-  AddFeatureAndFieldTrialFlags(enable_features_switch, disable_features_switch,
-                               cmd_line);
-}
-
-// static
-FieldTrial* FieldTrialList::CreateFieldTrial(
-    const std::string& name,
-    const std::string& group_name) {
-  DCHECK(global_);
-  DCHECK_GE(name.size(), 0u);
-  DCHECK_GE(group_name.size(), 0u);
-  if (name.empty() || group_name.empty() || !global_)
-    return nullptr;
-
-  FieldTrial* field_trial = FieldTrialList::Find(name);
-  if (field_trial) {
-    // In single process mode, or when we force them from the command line,
-    // we may have already created the field trial.
-    if (field_trial->group_name_internal() != group_name)
-      return nullptr;
-    return field_trial;
-  }
-  const int kTotalProbability = 100;
-  field_trial = new FieldTrial(name, kTotalProbability, group_name, 0);
-  FieldTrialList::Register(field_trial);
-  // Force the trial, which will also finalize the group choice.
-  field_trial->SetForced();
-  return field_trial;
-}
-
-// static
-bool FieldTrialList::AddObserver(Observer* observer) {
-  if (!global_)
-    return false;
-  global_->observer_list_->AddObserver(observer);
-  return true;
-}
-
-// static
-void FieldTrialList::RemoveObserver(Observer* observer) {
-  if (!global_)
-    return;
-  global_->observer_list_->RemoveObserver(observer);
-}
-
-// static
-void FieldTrialList::SetSynchronousObserver(Observer* observer) {
-  DCHECK(!global_->synchronous_observer_);
-  global_->synchronous_observer_ = observer;
-}
-
-// static
-void FieldTrialList::RemoveSynchronousObserver(Observer* observer) {
-  DCHECK_EQ(global_->synchronous_observer_, observer);
-  global_->synchronous_observer_ = nullptr;
-}
-
-// static
-void FieldTrialList::OnGroupFinalized(bool is_locked, FieldTrial* field_trial) {
-  if (!global_)
-    return;
-  if (is_locked) {
-    AddToAllocatorWhileLocked(global_->field_trial_allocator_.get(),
-                              field_trial);
-  } else {
-    AutoLock auto_lock(global_->lock_);
-    AddToAllocatorWhileLocked(global_->field_trial_allocator_.get(),
-                              field_trial);
-  }
-}
-
-// static
-void FieldTrialList::NotifyFieldTrialGroupSelection(FieldTrial* field_trial) {
-  if (!global_)
-    return;
-
-  {
-    AutoLock auto_lock(global_->lock_);
-    if (field_trial->group_reported_)
-      return;
-    field_trial->group_reported_ = true;
-
-    if (!field_trial->enable_field_trial_)
-      return;
-
-    if (kUseSharedMemoryForFieldTrials)
-      ActivateFieldTrialEntryWhileLocked(field_trial);
-  }
-
-  // Recording for stability debugging has to be done inline as a task posted
-  // to an observer may not get executed before a crash.
-  base::debug::GlobalActivityTracker* tracker =
-      base::debug::GlobalActivityTracker::Get();
-  if (tracker) {
-    tracker->RecordFieldTrial(field_trial->trial_name(),
-                              field_trial->group_name_internal());
-  }
-
-  if (global_->synchronous_observer_) {
-    global_->synchronous_observer_->OnFieldTrialGroupFinalized(
-        field_trial->trial_name(), field_trial->group_name_internal());
-  }
-
-  global_->observer_list_->Notify(
-      FROM_HERE, &FieldTrialList::Observer::OnFieldTrialGroupFinalized,
-      field_trial->trial_name(), field_trial->group_name_internal());
-}
-
-// static
-size_t FieldTrialList::GetFieldTrialCount() {
-  if (!global_)
-    return 0;
-  AutoLock auto_lock(global_->lock_);
-  return global_->registered_.size();
-}
-
-// static
-bool FieldTrialList::GetParamsFromSharedMemory(
-    FieldTrial* field_trial,
-    std::map<std::string, std::string>* params) {
-  DCHECK(global_);
-  // If the field trial allocator is not set up yet, then there are several
-  // cases:
-  //   - We are in the browser process and the allocator has not been set up
-  //   yet. If we got here, then we couldn't find the params in
-  //   FieldTrialParamAssociator, so it's definitely not here. Return false.
-  //   - Using shared memory for field trials is not enabled. If we got here,
-  //   then there's nothing in shared memory. Return false.
-  //   - We are in the child process and the allocator has not been set up yet.
-  //   If this is the case, then you are calling this too early. The field trial
-  //   allocator should get set up very early in the lifecycle. Try to see if
-  //   you can call it after it's been set up.
-  AutoLock auto_lock(global_->lock_);
-  if (!global_->field_trial_allocator_)
-    return false;
-
-  // If ref_ isn't set, then the field trial data can't be in shared memory.
-  if (!field_trial->ref_)
-    return false;
-
-  const FieldTrial::FieldTrialEntry* entry =
-      global_->field_trial_allocator_->GetAsObject<FieldTrial::FieldTrialEntry>(
-          field_trial->ref_);
-
-  size_t allocated_size =
-      global_->field_trial_allocator_->GetAllocSize(field_trial->ref_);
-  size_t actual_size = sizeof(FieldTrial::FieldTrialEntry) + entry->pickle_size;
-  if (allocated_size < actual_size)
-    return false;
-
-  return entry->GetParams(params);
-}
-
-// static
-void FieldTrialList::ClearParamsFromSharedMemoryForTesting() {
-  if (!global_)
-    return;
-
-  AutoLock auto_lock(global_->lock_);
-  if (!global_->field_trial_allocator_)
-    return;
-
-  // To clear the params, we iterate through every item in the allocator, copy
-  // just the trial and group name into a newly-allocated segment and then clear
-  // the existing item.
-  FieldTrialAllocator* allocator = global_->field_trial_allocator_.get();
-  FieldTrialAllocator::Iterator mem_iter(allocator);
-
-  // List of refs to eventually be made iterable. We can't make it in the loop,
-  // since it would go on forever.
-  std::vector<FieldTrial::FieldTrialRef> new_refs;
-
-  FieldTrial::FieldTrialRef prev_ref;
-  while ((prev_ref = mem_iter.GetNextOfType<FieldTrial::FieldTrialEntry>()) !=
-         FieldTrialAllocator::kReferenceNull) {
-    // Get the existing field trial entry in shared memory.
-    const FieldTrial::FieldTrialEntry* prev_entry =
-        allocator->GetAsObject<FieldTrial::FieldTrialEntry>(prev_ref);
-    StringPiece trial_name;
-    StringPiece group_name;
-    if (!prev_entry->GetTrialAndGroupName(&trial_name, &group_name))
-      continue;
-
-    // Write a new entry, minus the params.
-    Pickle pickle;
-    pickle.WriteString(trial_name);
-    pickle.WriteString(group_name);
-    size_t total_size = sizeof(FieldTrial::FieldTrialEntry) + pickle.size();
-    FieldTrial::FieldTrialEntry* new_entry =
-        allocator->New<FieldTrial::FieldTrialEntry>(total_size);
-    subtle::NoBarrier_Store(&new_entry->activated,
-                            subtle::NoBarrier_Load(&prev_entry->activated));
-    new_entry->pickle_size = pickle.size();
-
-    // TODO(lawrencewu): Modify base::Pickle to be able to write over a section
-    // in memory, so we can avoid this memcpy.
-    char* dst = reinterpret_cast<char*>(new_entry) +
-                sizeof(FieldTrial::FieldTrialEntry);
-    memcpy(dst, pickle.data(), pickle.size());
-
-    // Update the ref on the field trial and add it to the list to be made
-    // iterable.
-    FieldTrial::FieldTrialRef new_ref = allocator->GetAsReference(new_entry);
-    FieldTrial* trial = global_->PreLockedFind(trial_name.as_string());
-    trial->ref_ = new_ref;
-    new_refs.push_back(new_ref);
-
-    // Mark the existing entry as unused.
-    allocator->ChangeType(prev_ref, 0,
-                          FieldTrial::FieldTrialEntry::kPersistentTypeId,
-                          /*clear=*/false);
-  }
-
-  for (const auto& ref : new_refs) {
-    allocator->MakeIterable(ref);
-  }
-}
-
-// static
-void FieldTrialList::DumpAllFieldTrialsToPersistentAllocator(
-    PersistentMemoryAllocator* allocator) {
-  if (!global_)
-    return;
-  AutoLock auto_lock(global_->lock_);
-  for (const auto& registered : global_->registered_) {
-    AddToAllocatorWhileLocked(allocator, registered.second);
-  }
-}
-
-// static
-std::vector<const FieldTrial::FieldTrialEntry*>
-FieldTrialList::GetAllFieldTrialsFromPersistentAllocator(
-    PersistentMemoryAllocator const& allocator) {
-  std::vector<const FieldTrial::FieldTrialEntry*> entries;
-  FieldTrialAllocator::Iterator iter(&allocator);
-  const FieldTrial::FieldTrialEntry* entry;
-  while ((entry = iter.GetNextOfObject<FieldTrial::FieldTrialEntry>()) !=
-         nullptr) {
-    entries.push_back(entry);
-  }
-  return entries;
-}
-
-// static
-bool FieldTrialList::IsGlobalSetForTesting() {
-  return global_ != nullptr;
-}
-
-// static
-std::string FieldTrialList::SerializeSharedMemoryHandleMetadata(
-    const SharedMemoryHandle& shm) {
-  std::stringstream ss;
-#if defined(OS_WIN)
-  // Tell the child process the name of the inherited HANDLE.
-  uintptr_t uintptr_handle = reinterpret_cast<uintptr_t>(shm.GetHandle());
-  ss << uintptr_handle << ",";
-#elif defined(OS_FUCHSIA)
-  ss << shm.GetHandle() << ",";
-#elif !defined(OS_POSIX)
-#error Unsupported OS
-#endif
-
-  base::UnguessableToken guid = shm.GetGUID();
-  ss << guid.GetHighForSerialization() << "," << guid.GetLowForSerialization();
-  ss << "," << shm.GetSize();
-  return ss.str();
-}
-
-#if defined(OS_WIN) || defined(OS_FUCHSIA)
-
-// static
-SharedMemoryHandle FieldTrialList::DeserializeSharedMemoryHandleMetadata(
-    const std::string& switch_value) {
-  std::vector<base::StringPiece> tokens = base::SplitStringPiece(
-      switch_value, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
-
-  if (tokens.size() != 4)
-    return SharedMemoryHandle();
-
-  int field_trial_handle = 0;
-  if (!base::StringToInt(tokens[0], &field_trial_handle))
-    return SharedMemoryHandle();
-#if defined(OS_FUCHSIA)
-  zx_handle_t handle = static_cast<zx_handle_t>(field_trial_handle);
-#elif defined(OS_WIN)
-  HANDLE handle =
-      reinterpret_cast<HANDLE>(static_cast<uintptr_t>(field_trial_handle));
-  if (base::IsCurrentProcessElevated()) {
-    // base::LaunchElevatedProcess doesn't have a way to duplicate the handle,
-    // but this process can since by definition it's not sandboxed.
-    base::ProcessId parent_pid = base::GetParentProcessId(GetCurrentProcess());
-    HANDLE parent_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, parent_pid);
-    DuplicateHandle(parent_handle, handle, GetCurrentProcess(), &handle, 0,
-                    FALSE, DUPLICATE_SAME_ACCESS);
-    CloseHandle(parent_handle);
-  }
-#endif  // defined(OS_WIN)
-
-  base::UnguessableToken guid;
-  if (!DeserializeGUIDFromStringPieces(tokens[1], tokens[2], &guid))
-    return SharedMemoryHandle();
-
-  int size;
-  if (!base::StringToInt(tokens[3], &size))
-    return SharedMemoryHandle();
-
-  return SharedMemoryHandle(handle, static_cast<size_t>(size), guid);
-}
-
-#elif defined(OS_POSIX) && !defined(OS_NACL)
-
-// static
-SharedMemoryHandle FieldTrialList::DeserializeSharedMemoryHandleMetadata(
-    int fd,
-    const std::string& switch_value) {
-  std::vector<base::StringPiece> tokens = base::SplitStringPiece(
-      switch_value, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
-
-  if (tokens.size() != 3)
-    return SharedMemoryHandle();
-
-  base::UnguessableToken guid;
-  if (!DeserializeGUIDFromStringPieces(tokens[0], tokens[1], &guid))
-    return SharedMemoryHandle();
-
-  int size;
-  if (!base::StringToInt(tokens[2], &size))
-    return SharedMemoryHandle();
-
-  return SharedMemoryHandle(FileDescriptor(fd, true), static_cast<size_t>(size),
-                            guid);
-}
-
-#endif
-
-#if defined(OS_WIN) || defined(OS_FUCHSIA)
-// static
-bool FieldTrialList::CreateTrialsFromSwitchValue(
-    const std::string& switch_value) {
-  SharedMemoryHandle shm = DeserializeSharedMemoryHandleMetadata(switch_value);
-  if (!shm.IsValid())
-    return false;
-  return FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm);
-}
-#elif defined(OS_POSIX) && !defined(OS_NACL)
-// static
-bool FieldTrialList::CreateTrialsFromDescriptor(
-    int fd_key,
-    const std::string& switch_value) {
-  if (!kUseSharedMemoryForFieldTrials)
-    return false;
-
-  if (fd_key == -1)
-    return false;
-
-  int fd = GlobalDescriptors::GetInstance()->MaybeGet(fd_key);
-  if (fd == -1)
-    return false;
-
-  SharedMemoryHandle shm =
-      DeserializeSharedMemoryHandleMetadata(fd, switch_value);
-  if (!shm.IsValid())
-    return false;
-
-  bool result = FieldTrialList::CreateTrialsFromSharedMemoryHandle(shm);
-  DCHECK(result);
-  return true;
-}
-#endif  // defined(OS_POSIX) && !defined(OS_NACL)
-
-// static
-bool FieldTrialList::CreateTrialsFromSharedMemoryHandle(
-    SharedMemoryHandle shm_handle) {
-  // shm gets deleted when it gets out of scope, but that's OK because we need
-  // it only for the duration of this method.
-  std::unique_ptr<SharedMemory> shm(new SharedMemory(shm_handle, true));
-  if (!shm.get()->Map(kFieldTrialAllocationSize))
-    OnOutOfMemory(kFieldTrialAllocationSize);
-
-  return FieldTrialList::CreateTrialsFromSharedMemory(std::move(shm));
-}
-
-// static
-bool FieldTrialList::CreateTrialsFromSharedMemory(
-    std::unique_ptr<SharedMemory> shm) {
-  global_->field_trial_allocator_.reset(
-      new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, true));
-  FieldTrialAllocator* shalloc = global_->field_trial_allocator_.get();
-  FieldTrialAllocator::Iterator mem_iter(shalloc);
-
-  const FieldTrial::FieldTrialEntry* entry;
-  while ((entry = mem_iter.GetNextOfObject<FieldTrial::FieldTrialEntry>()) !=
-         nullptr) {
-    StringPiece trial_name;
-    StringPiece group_name;
-    if (!entry->GetTrialAndGroupName(&trial_name, &group_name))
-      return false;
-
-    // TODO(lawrencewu): Convert the API for CreateFieldTrial to take
-    // StringPieces.
-    FieldTrial* trial =
-        CreateFieldTrial(trial_name.as_string(), group_name.as_string());
-
-    trial->ref_ = mem_iter.GetAsReference(entry);
-    if (subtle::NoBarrier_Load(&entry->activated)) {
-      // Call |group()| to mark the trial as "used" and notify observers, if
-      // any. This is useful to ensure that field trials created in child
-      // processes are properly reported in crash reports.
-      trial->group();
-    }
-  }
-  return true;
-}
-
-// static
-void FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded() {
-  if (!global_)
-    return;
-  AutoLock auto_lock(global_->lock_);
-  // Create the allocator if not already created and add all existing trials.
-  if (global_->field_trial_allocator_ != nullptr)
-    return;
-
-  SharedMemoryCreateOptions options;
-  options.size = kFieldTrialAllocationSize;
-  options.share_read_only = true;
-#if defined(OS_MACOSX) && !defined(OS_IOS)
-  options.type = SharedMemoryHandle::POSIX;
-#endif
-
-  std::unique_ptr<SharedMemory> shm(new SharedMemory());
-  if (!shm->Create(options))
-    OnOutOfMemory(kFieldTrialAllocationSize);
-
-  if (!shm->Map(kFieldTrialAllocationSize))
-    OnOutOfMemory(kFieldTrialAllocationSize);
-
-  global_->field_trial_allocator_.reset(
-      new FieldTrialAllocator(std::move(shm), 0, kAllocatorName, false));
-  global_->field_trial_allocator_->CreateTrackingHistograms(kAllocatorName);
-
-  // Add all existing field trials.
-  for (const auto& registered : global_->registered_) {
-    AddToAllocatorWhileLocked(global_->field_trial_allocator_.get(),
-                              registered.second);
-  }
-
-  // Add all existing features.
-  FeatureList::GetInstance()->AddFeaturesToAllocator(
-      global_->field_trial_allocator_.get());
-
-#if !defined(OS_NACL)
-  global_->readonly_allocator_handle_ = GetSharedMemoryReadOnlyHandle(
-      global_->field_trial_allocator_->shared_memory());
-#endif
-}
-
-// static
-void FieldTrialList::AddToAllocatorWhileLocked(
-    PersistentMemoryAllocator* allocator,
-    FieldTrial* field_trial) {
-  // Don't do anything if the allocator hasn't been instantiated yet.
-  if (allocator == nullptr)
-    return;
-
-  // Or if the allocator is read only, which means we are in a child process and
-  // shouldn't be writing to it.
-  if (allocator->IsReadonly())
-    return;
-
-  FieldTrial::State trial_state;
-  if (!field_trial->GetStateWhileLocked(&trial_state, false))
-    return;
-
-  // Or if we've already added it. We must check after GetState since it can
-  // also add to the allocator.
-  if (field_trial->ref_)
-    return;
-
-  Pickle pickle;
-  PickleFieldTrial(trial_state, &pickle);
-
-  size_t total_size = sizeof(FieldTrial::FieldTrialEntry) + pickle.size();
-  FieldTrial::FieldTrialRef ref = allocator->Allocate(
-      total_size, FieldTrial::FieldTrialEntry::kPersistentTypeId);
-  if (ref == FieldTrialAllocator::kReferenceNull) {
-    NOTREACHED();
-    return;
-  }
-
-  FieldTrial::FieldTrialEntry* entry =
-      allocator->GetAsObject<FieldTrial::FieldTrialEntry>(ref);
-  subtle::NoBarrier_Store(&entry->activated, trial_state.activated);
-  entry->pickle_size = pickle.size();
-
-  // TODO(lawrencewu): Modify base::Pickle to be able to write over a section in
-  // memory, so we can avoid this memcpy.
-  char* dst =
-      reinterpret_cast<char*>(entry) + sizeof(FieldTrial::FieldTrialEntry);
-  memcpy(dst, pickle.data(), pickle.size());
-
-  allocator->MakeIterable(ref);
-  field_trial->ref_ = ref;
-}
-
-// static
-void FieldTrialList::ActivateFieldTrialEntryWhileLocked(
-    FieldTrial* field_trial) {
-  FieldTrialAllocator* allocator = global_->field_trial_allocator_.get();
-
-  // Check if we're in the child process and return early if so.
-  if (!allocator || allocator->IsReadonly())
-    return;
-
-  FieldTrial::FieldTrialRef ref = field_trial->ref_;
-  if (ref == FieldTrialAllocator::kReferenceNull) {
-    // It's fine to do this even if the allocator hasn't been instantiated
-    // yet -- it'll just return early.
-    AddToAllocatorWhileLocked(allocator, field_trial);
-  } else {
-    // It's also okay to do this even though the callee doesn't have a lock --
-    // the only thing that happens on a stale read here is a slight performance
-    // hit from the child re-synchronizing activation state.
-    FieldTrial::FieldTrialEntry* entry =
-        allocator->GetAsObject<FieldTrial::FieldTrialEntry>(ref);
-    subtle::NoBarrier_Store(&entry->activated, 1);
-  }
-}
-
-// static
-const FieldTrial::EntropyProvider*
-    FieldTrialList::GetEntropyProviderForOneTimeRandomization() {
-  if (!global_) {
-    used_without_global_ = true;
-    return nullptr;
-  }
-
-  return global_->entropy_provider_.get();
-}
-
-FieldTrial* FieldTrialList::PreLockedFind(const std::string& name) {
-  RegistrationMap::iterator it = registered_.find(name);
-  if (registered_.end() == it)
-    return nullptr;
-  return it->second;
-}
-
-// static
-void FieldTrialList::Register(FieldTrial* trial) {
-  if (!global_) {
-    used_without_global_ = true;
-    return;
-  }
-  AutoLock auto_lock(global_->lock_);
-  CHECK(!global_->PreLockedFind(trial->trial_name())) << trial->trial_name();
-  trial->AddRef();
-  trial->SetTrialRegistered();
-  global_->registered_[trial->trial_name()] = trial;
-}
-
-// static
-FieldTrialList::RegistrationMap FieldTrialList::GetRegisteredTrials() {
-  RegistrationMap output;
-  if (global_) {
-    AutoLock auto_lock(global_->lock_);
-    output = global_->registered_;
-  }
-  return output;
-}
-
-}  // namespace base
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h
deleted file mode 100644
index d5d6cb8..0000000
--- a/base/metrics/field_trial.h
+++ /dev/null
@@ -1,802 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// FieldTrial is a class for handling details of statistical experiments
-// performed by actual users in the field (i.e., in a shipped or beta product).
-// All code is called exclusively on the UI thread currently.
-//
-// The simplest example is an experiment to see whether one of two options
-// produces "better" results across our user population.  In that scenario, UMA
-// data is uploaded to aggregate the test results, and this FieldTrial class
-// manages the state of each such experiment (state == which option was
-// pseudo-randomly selected).
-//
-// States are typically generated randomly, either based on a one time
-// randomization (which will yield the same results, in terms of selecting
-// the client for a field trial or not, for every run of the program on a
-// given machine), or by a session randomization (generated each time the
-// application starts up, but held constant during the duration of the
-// process).
-
-//------------------------------------------------------------------------------
-// Example:  Suppose we have an experiment involving memory, such as determining
-// the impact of some pruning algorithm.
-// We assume that we already have a histogram of memory usage, such as:
-
-//   UMA_HISTOGRAM_COUNTS("Memory.RendererTotal", count);
-
-// Somewhere in main thread initialization code, we'd probably define an
-// instance of a FieldTrial, with code such as:
-
-// // FieldTrials are reference counted, and persist automagically until
-// // process teardown, courtesy of their automatic registration in
-// // FieldTrialList.
-// // Note: This field trial will run in Chrome instances compiled through
-// //       8 July, 2015, and after that all instances will be in "StandardMem".
-// scoped_refptr<base::FieldTrial> trial(
-//     base::FieldTrialList::FactoryGetFieldTrial(
-//         "MemoryExperiment", 1000, "StandardMem", 2015, 7, 8,
-//         base::FieldTrial::ONE_TIME_RANDOMIZED, NULL));
-//
-// const int high_mem_group =
-//     trial->AppendGroup("HighMem", 20);  // 2% in HighMem group.
-// const int low_mem_group =
-//     trial->AppendGroup("LowMem", 20);   // 2% in LowMem group.
-// // Take action depending of which group we randomly land in.
-// if (trial->group() == high_mem_group)
-//   SetPruningAlgorithm(kType1);  // Sample setting of browser state.
-// else if (trial->group() == low_mem_group)
-//   SetPruningAlgorithm(kType2);  // Sample alternate setting.
-
-//------------------------------------------------------------------------------
-
-#ifndef BASE_METRICS_FIELD_TRIAL_H_
-#define BASE_METRICS_FIELD_TRIAL_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/atomicops.h"
-#include "base/base_export.h"
-#include "base/command_line.h"
-#include "base/feature_list.h"
-#include "base/files/file.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/shared_memory.h"
-#include "base/memory/shared_memory_handle.h"
-#include "base/metrics/persistent_memory_allocator.h"
-#include "base/observer_list_threadsafe.h"
-#include "base/pickle.h"
-#include "base/process/launch.h"
-#include "base/strings/string_piece.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
-#include "build_config.h"
-
-namespace base {
-
-class FieldTrialList;
-
-class BASE_EXPORT FieldTrial : public RefCounted<FieldTrial> {
- public:
-  typedef int Probability;  // Probability type for being selected in a trial.
-
-  // TODO(665129): Make private again after crash has been resolved.
-  typedef SharedPersistentMemoryAllocator::Reference FieldTrialRef;
-
-  // Specifies the persistence of the field trial group choice.
-  enum RandomizationType {
-    // One time randomized trials will persist the group choice between
-    // restarts, which is recommended for most trials, especially those that
-    // change user visible behavior.
-    ONE_TIME_RANDOMIZED,
-    // Session randomized trials will roll the dice to select a group on every
-    // process restart.
-    SESSION_RANDOMIZED,
-  };
-
-  // EntropyProvider is an interface for providing entropy for one-time
-  // randomized (persistent) field trials.
-  class BASE_EXPORT EntropyProvider {
-   public:
-    virtual ~EntropyProvider();
-
-    // Returns a double in the range of [0, 1) to be used for the dice roll for
-    // the specified field trial. If |randomization_seed| is not 0, it will be
-    // used in preference to |trial_name| for generating the entropy by entropy
-    // providers that support it. A given instance should always return the same
-    // value given the same input |trial_name| and |randomization_seed| values.
-    virtual double GetEntropyForTrial(const std::string& trial_name,
-                                      uint32_t randomization_seed) const = 0;
-  };
-
-  // A pair representing a Field Trial and its selected group.
-  struct ActiveGroup {
-    std::string trial_name;
-    std::string group_name;
-  };
-
-  // A triplet representing a FieldTrial, its selected group and whether it's
-  // active. String members are pointers to the underlying strings owned by the
-  // FieldTrial object. Does not use StringPiece to avoid conversions back to
-  // std::string.
-  struct BASE_EXPORT State {
-    const std::string* trial_name = nullptr;
-    const std::string* group_name = nullptr;
-    bool activated = false;
-
-    State();
-    State(const State& other);
-    ~State();
-  };
-
-  // We create one FieldTrialEntry per field trial in shared memory, via
-  // AddToAllocatorWhileLocked. The FieldTrialEntry is followed by a
-  // base::Pickle object that we unpickle and read from.
-  struct BASE_EXPORT FieldTrialEntry {
-    // SHA1(FieldTrialEntry): Increment this if structure changes!
-    static constexpr uint32_t kPersistentTypeId = 0xABA17E13 + 2;
-
-    // Expected size for 32/64-bit check.
-    static constexpr size_t kExpectedInstanceSize = 8;
-
-    // Whether or not this field trial is activated. This is really just a
-    // boolean but using a 32 bit value for portability reasons. It should be
-    // accessed via NoBarrier_Load()/NoBarrier_Store() to prevent the compiler
-    // from doing unexpected optimizations because it thinks that only one
-    // thread is accessing the memory location.
-    subtle::Atomic32 activated;
-
-    // Size of the pickled structure, NOT the total size of this entry.
-    uint32_t pickle_size;
-
-    // Calling this is only valid when the entry is initialized. That is, it
-    // resides in shared memory and has a pickle containing the trial name and
-    // group name following it.
-    bool GetTrialAndGroupName(StringPiece* trial_name,
-                              StringPiece* group_name) const;
-
-    // Calling this is only valid when the entry is initialized as well. Reads
-    // the parameters following the trial and group name and stores them as
-    // key-value mappings in |params|.
-    bool GetParams(std::map<std::string, std::string>* params) const;
-
-   private:
-    // Returns an iterator over the data containing names and params.
-    PickleIterator GetPickleIterator() const;
-
-    // Takes the iterator and writes out the first two items into |trial_name|
-    // and |group_name|.
-    bool ReadStringPair(PickleIterator* iter,
-                        StringPiece* trial_name,
-                        StringPiece* group_name) const;
-  };
-
-  typedef std::vector<ActiveGroup> ActiveGroups;
-
-  // A return value to indicate that a given instance has not yet had a group
-  // assignment (and hence is not yet participating in the trial).
-  static const int kNotFinalized;
-
-  // Disables this trial, meaning it always determines the default group
-  // has been selected. May be called immediately after construction, or
-  // at any time after initialization (should not be interleaved with
-  // AppendGroup calls). Once disabled, there is no way to re-enable a
-  // trial.
-  // TODO(mad): http://code.google.com/p/chromium/issues/detail?id=121446
-  // This doesn't properly reset to Default when a group was forced.
-  void Disable();
-
-  // Establish the name and probability of the next group in this trial.
-  // Sometimes, based on construction randomization, this call may cause the
-  // provided group to be *THE* group selected for use in this instance.
-  // The return value is the group number of the new group.
-  int AppendGroup(const std::string& name, Probability group_probability);
-
-  // Return the name of the FieldTrial (excluding the group name).
-  const std::string& trial_name() const { return trial_name_; }
-
-  // Return the randomly selected group number that was assigned, and notify
-  // any/all observers that this finalized group number has presumably been used
-  // (queried), and will never change. Note that this will force an instance to
-  // participate, and make it illegal to attempt to probabilistically add any
-  // other groups to the trial.
-  int group();
-
-  // If the group's name is empty, a string version containing the group number
-  // is used as the group name. This causes a winner to be chosen if none was.
-  const std::string& group_name();
-
-  // Finalizes the group choice and returns the chosen group, but does not mark
-  // the trial as active - so its state will not be reported until group_name()
-  // or similar is called.
-  const std::string& GetGroupNameWithoutActivation();
-
-  // Set the field trial as forced, meaning that it was setup earlier than
-  // the hard coded registration of the field trial to override it.
-  // This allows the code that was hard coded to register the field trial to
-  // still succeed even though the field trial has already been registered.
-  // This must be called after appending all the groups, since we will make
-  // the group choice here. Note that this is a NOOP for already forced trials.
-  // And, as the rest of the FieldTrial code, this is not thread safe and must
-  // be done from the UI thread.
-  void SetForced();
-
-  // Enable benchmarking sets field trials to a common setting.
-  static void EnableBenchmarking();
-
-  // Creates a FieldTrial object with the specified parameters, to be used for
-  // simulation of group assignment without actually affecting global field
-  // trial state in the running process. Group assignment will be done based on
-  // |entropy_value|, which must have a range of [0, 1).
-  //
-  // Note: Using this function will not register the field trial globally in the
-  // running process - for that, use FieldTrialList::FactoryGetFieldTrial().
-  //
-  // The ownership of the returned FieldTrial is transfered to the caller which
-  // is responsible for deref'ing it (e.g. by using scoped_refptr<FieldTrial>).
-  static FieldTrial* CreateSimulatedFieldTrial(
-      const std::string& trial_name,
-      Probability total_probability,
-      const std::string& default_group_name,
-      double entropy_value);
-
- private:
-  // Allow tests to access our innards for testing purposes.
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Registration);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AbsoluteProbabilities);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, RemainingProbability);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FiftyFiftyProbability);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, MiddleProbabilities);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, OneWinner);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DisableProbability);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, ActiveGroups);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, AllGroups);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, ActiveGroupsNotFinalized);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, Save);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SaveAll);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DuplicateRestore);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedTurnFeatureOff);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedTurnFeatureOn);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedChangeDefault_Default);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, SetForcedChangeDefault_NonDefault);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, FloatBoundariesGiveEqualGroupSizes);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialTest, DoesNotSurpassTotalProbability);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest,
-                           DoNotAddSimulatedFieldTrialsToAllocator);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, ClearParamsFromSharedMemory);
-
-  friend class base::FieldTrialList;
-
-  friend class RefCounted<FieldTrial>;
-
-  // This is the group number of the 'default' group when a choice wasn't forced
-  // by a call to FieldTrialList::CreateFieldTrial. It is kept private so that
-  // consumers don't use it by mistake in cases where the group was forced.
-  static const int kDefaultGroupNumber;
-
-  // Creates a field trial with the specified parameters. Group assignment will
-  // be done based on |entropy_value|, which must have a range of [0, 1).
-  FieldTrial(const std::string& trial_name,
-             Probability total_probability,
-             const std::string& default_group_name,
-             double entropy_value);
-  virtual ~FieldTrial();
-
-  // Return the default group name of the FieldTrial.
-  std::string default_group_name() const { return default_group_name_; }
-
-  // Marks this trial as having been registered with the FieldTrialList. Must be
-  // called no more than once and before any |group()| calls have occurred.
-  void SetTrialRegistered();
-
-  // Sets the chosen group name and number.
-  void SetGroupChoice(const std::string& group_name, int number);
-
-  // Ensures that a group is chosen, if it hasn't yet been. The field trial
-  // might yet be disabled, so this call will *not* notify observers of the
-  // status.
-  void FinalizeGroupChoice();
-
-  // Implements FinalizeGroupChoice() with the added flexibility of being
-  // deadlock-free if |is_locked| is true and the caller is holding a lock.
-  void FinalizeGroupChoiceImpl(bool is_locked);
-
-  // Returns the trial name and selected group name for this field trial via
-  // the output parameter |active_group|, but only if the group has already
-  // been chosen and has been externally observed via |group()| and the trial
-  // has not been disabled. In that case, true is returned and |active_group|
-  // is filled in; otherwise, the result is false and |active_group| is left
-  // untouched.
-  bool GetActiveGroup(ActiveGroup* active_group) const;
-
-  // Returns the trial name and selected group name for this field trial via
-  // the output parameter |field_trial_state| for all the studies when
-  // |bool include_expired| is true. In case when |bool include_expired| is
-  // false, if the trial has not been disabled true is returned and
-  // |field_trial_state| is filled in; otherwise, the result is false and
-  // |field_trial_state| is left untouched.
-  // This function is deadlock-free if the caller is holding a lock.
-  bool GetStateWhileLocked(State* field_trial_state, bool include_expired);
-
-  // Returns the group_name. A winner need not have been chosen.
-  std::string group_name_internal() const { return group_name_; }
-
-  // The name of the field trial, as can be found via the FieldTrialList.
-  const std::string trial_name_;
-
-  // The maximum sum of all probabilities supplied, which corresponds to 100%.
-  // This is the scaling factor used to adjust supplied probabilities.
-  const Probability divisor_;
-
-  // The name of the default group.
-  const std::string default_group_name_;
-
-  // The randomly selected probability that is used to select a group (or have
-  // the instance not participate).  It is the product of divisor_ and a random
-  // number between [0, 1).
-  Probability random_;
-
-  // Sum of the probabilities of all appended groups.
-  Probability accumulated_group_probability_;
-
-  // The number that will be returned by the next AppendGroup() call.
-  int next_group_number_;
-
-  // The pseudo-randomly assigned group number.
-  // This is kNotFinalized if no group has been assigned.
-  int group_;
-
-  // A textual name for the randomly selected group. Valid after |group()|
-  // has been called.
-  std::string group_name_;
-
-  // When enable_field_trial_ is false, field trial reverts to the 'default'
-  // group.
-  bool enable_field_trial_;
-
-  // When forced_ is true, we return the chosen group from AppendGroup when
-  // appropriate.
-  bool forced_;
-
-  // Specifies whether the group choice has been reported to observers.
-  bool group_reported_;
-
-  // Whether this trial is registered with the global FieldTrialList and thus
-  // should notify it when its group is queried.
-  bool trial_registered_;
-
-  // Reference to related field trial struct and data in shared memory.
-  FieldTrialRef ref_;
-
-  // When benchmarking is enabled, field trials all revert to the 'default'
-  // group.
-  static bool enable_benchmarking_;
-
-  DISALLOW_COPY_AND_ASSIGN(FieldTrial);
-};
-
-//------------------------------------------------------------------------------
-// Class with a list of all active field trials.  A trial is active if it has
-// been registered, which includes evaluating its state based on its probaility.
-// Only one instance of this class exists and outside of testing, will live for
-// the entire life time of the process.
-class BASE_EXPORT FieldTrialList {
- public:
-  typedef SharedPersistentMemoryAllocator FieldTrialAllocator;
-
-  // Type for function pointer passed to |AllParamsToString| used to escape
-  // special characters from |input|.
-  typedef std::string (*EscapeDataFunc)(const std::string& input);
-
-  // Year that is guaranteed to not be expired when instantiating a field trial
-  // via |FactoryGetFieldTrial()|.  Set to two years from the build date.
-  static int kNoExpirationYear;
-
-  // Observer is notified when a FieldTrial's group is selected.
-  class BASE_EXPORT Observer {
-   public:
-    // Notify observers when FieldTrials's group is selected.
-    virtual void OnFieldTrialGroupFinalized(const std::string& trial_name,
-                                            const std::string& group_name) = 0;
-
-   protected:
-    virtual ~Observer();
-  };
-
-  // This singleton holds the global list of registered FieldTrials.
-  //
-  // To support one-time randomized field trials, specify a non-null
-  // |entropy_provider| which should be a source of uniformly distributed
-  // entropy values. If one time randomization is not desired, pass in null for
-  // |entropy_provider|.
-  explicit FieldTrialList(
-      std::unique_ptr<const FieldTrial::EntropyProvider> entropy_provider);
-
-  // Destructor Release()'s references to all registered FieldTrial instances.
-  ~FieldTrialList();
-
-  // Get a FieldTrial instance from the factory.
-  //
-  // |name| is used to register the instance with the FieldTrialList class,
-  // and can be used to find the trial (only one trial can be present for each
-  // name). |default_group_name| is the name of the default group which will
-  // be chosen if none of the subsequent appended groups get to be chosen.
-  // |default_group_number| can receive the group number of the default group as
-  // AppendGroup returns the number of the subsequence groups. |trial_name| and
-  // |default_group_name| may not be empty but |default_group_number| can be
-  // NULL if the value is not needed.
-  //
-  // Group probabilities that are later supplied must sum to less than or equal
-  // to the |total_probability|. Arguments |year|, |month| and |day_of_month|
-  // specify the expiration time. If the build time is after the expiration time
-  // then the field trial reverts to the 'default' group.
-  //
-  // Use this static method to get a startup-randomized FieldTrial or a
-  // previously created forced FieldTrial.
-  static FieldTrial* FactoryGetFieldTrial(
-      const std::string& trial_name,
-      FieldTrial::Probability total_probability,
-      const std::string& default_group_name,
-      const int year,
-      const int month,
-      const int day_of_month,
-      FieldTrial::RandomizationType randomization_type,
-      int* default_group_number);
-
-  // Same as FactoryGetFieldTrial(), but allows specifying a custom seed to be
-  // used on one-time randomized field trials (instead of a hash of the trial
-  // name, which is used otherwise or if |randomization_seed| has value 0). The
-  // |randomization_seed| value (other than 0) should never be the same for two
-  // trials, else this would result in correlated group assignments.  Note:
-  // Using a custom randomization seed is only supported by the
-  // PermutedEntropyProvider (which is used when UMA is not enabled). If
-  // |override_entropy_provider| is not null, then it will be used for
-  // randomization instead of the provider given when the FieldTrialList was
-  // instantiated.
-  static FieldTrial* FactoryGetFieldTrialWithRandomizationSeed(
-      const std::string& trial_name,
-      FieldTrial::Probability total_probability,
-      const std::string& default_group_name,
-      const int year,
-      const int month,
-      const int day_of_month,
-      FieldTrial::RandomizationType randomization_type,
-      uint32_t randomization_seed,
-      int* default_group_number,
-      const FieldTrial::EntropyProvider* override_entropy_provider);
-
-  // The Find() method can be used to test to see if a named trial was already
-  // registered, or to retrieve a pointer to it from the global map.
-  static FieldTrial* Find(const std::string& trial_name);
-
-  // Returns the group number chosen for the named trial, or
-  // FieldTrial::kNotFinalized if the trial does not exist.
-  static int FindValue(const std::string& trial_name);
-
-  // Returns the group name chosen for the named trial, or the empty string if
-  // the trial does not exist. The first call of this function on a given field
-  // trial will mark it as active, so that its state will be reported with usage
-  // metrics, crashes, etc.
-  static std::string FindFullName(const std::string& trial_name);
-
-  // Returns true if the named trial has been registered.
-  static bool TrialExists(const std::string& trial_name);
-
-  // Returns true if the named trial exists and has been activated.
-  static bool IsTrialActive(const std::string& trial_name);
-
-  // Creates a persistent representation of active FieldTrial instances for
-  // resurrection in another process. This allows randomization to be done in
-  // one process, and secondary processes can be synchronized on the result.
-  // The resulting string contains the name and group name pairs of all
-  // registered FieldTrials for which the group has been chosen and externally
-  // observed (via |group()|) and which have not been disabled, with "/" used
-  // to separate all names and to terminate the string. This string is parsed
-  // by |CreateTrialsFromString()|.
-  static void StatesToString(std::string* output);
-
-  // Creates a persistent representation of all FieldTrial instances for
-  // resurrection in another process. This allows randomization to be done in
-  // one process, and secondary processes can be synchronized on the result.
-  // The resulting string contains the name and group name pairs of all
-  // registered FieldTrials including disabled based on |include_expired|,
-  // with "/" used to separate all names and to terminate the string. All
-  // activated trials have their name prefixed with "*". This string is parsed
-  // by |CreateTrialsFromString()|.
-  static void AllStatesToString(std::string* output, bool include_expired);
-
-  // Creates a persistent representation of all FieldTrial params for
-  // resurrection in another process. The returned string contains the trial
-  // name and group name pairs of all registered FieldTrials including disabled
-  // based on |include_expired| separated by '.'. The pair is followed by ':'
-  // separator and list of param name and values separated by '/'. It also takes
-  // |encode_data_func| function pointer for encodeing special charactors.
-  // This string is parsed by |AssociateParamsFromString()|.
-  static std::string AllParamsToString(bool include_expired,
-                                       EscapeDataFunc encode_data_func);
-
-  // Fills in the supplied vector |active_groups| (which must be empty when
-  // called) with a snapshot of all registered FieldTrials for which the group
-  // has been chosen and externally observed (via |group()|) and which have
-  // not been disabled.
-  static void GetActiveFieldTrialGroups(
-      FieldTrial::ActiveGroups* active_groups);
-
-  // Returns the field trials that are marked active in |trials_string|.
-  static void GetActiveFieldTrialGroupsFromString(
-      const std::string& trials_string,
-      FieldTrial::ActiveGroups* active_groups);
-
-  // Returns the field trials that were active when the process was
-  // created. Either parses the field trial string or the shared memory
-  // holding field trial information.
-  // Must be called only after a call to CreateTrialsFromCommandLine().
-  static void GetInitiallyActiveFieldTrials(
-      const base::CommandLine& command_line,
-      FieldTrial::ActiveGroups* active_groups);
-
-  // Use a state string (re: StatesToString()) to augment the current list of
-  // field trials to include the supplied trials, and using a 100% probability
-  // for each trial, force them to have the same group string. This is commonly
-  // used in a non-browser process, to carry randomly selected state in a
-  // browser process into this non-browser process, but could also be invoked
-  // through a command line argument to the browser process. Created field
-  // trials will be marked "used" for the purposes of active trial reporting
-  // if they are prefixed with |kActivationMarker|. Trial names in
-  // |ignored_trial_names| are ignored when parsing |trials_string|.
-  static bool CreateTrialsFromString(
-      const std::string& trials_string,
-      const std::set<std::string>& ignored_trial_names);
-
-  // Achieves the same thing as CreateTrialsFromString, except wraps the logic
-  // by taking in the trials from the command line, either via shared memory
-  // handle or command line argument. A bit of a misnomer since on POSIX we
-  // simply get the trials from opening |fd_key| if using shared memory. On
-  // Windows, we expect the |cmd_line| switch for |field_trial_handle_switch| to
-  // contain the shared memory handle that contains the field trial allocator.
-  // We need the |field_trial_handle_switch| and |fd_key| arguments to be passed
-  // in since base/ can't depend on content/.
-  static void CreateTrialsFromCommandLine(const base::CommandLine& cmd_line,
-                                          const char* field_trial_handle_switch,
-                                          int fd_key);
-
-  // Creates base::Feature overrides from the command line by first trying to
-  // use shared memory and then falling back to the command line if it fails.
-  static void CreateFeaturesFromCommandLine(
-      const base::CommandLine& command_line,
-      const char* enable_features_switch,
-      const char* disable_features_switch,
-      FeatureList* feature_list);
-
-#if defined(OS_WIN)
-  // On Windows, we need to explicitly pass down any handles to be inherited.
-  // This function adds the shared memory handle to field trial state to the
-  // list of handles to be inherited.
-  static void AppendFieldTrialHandleIfNeeded(
-      base::HandlesToInheritVector* handles);
-#elif defined(OS_FUCHSIA)
-  // TODO(fuchsia): Implement shared-memory configuration (crbug.com/752368).
-#elif defined(OS_POSIX) && !defined(OS_NACL)
-  // On POSIX, we also need to explicitly pass down this file descriptor that
-  // should be shared with the child process. Returns an invalid handle if it
-  // was not initialized properly.
-  static base::SharedMemoryHandle GetFieldTrialHandle();
-#endif
-
-  // Adds a switch to the command line containing the field trial state as a
-  // string (if not using shared memory to share field trial state), or the
-  // shared memory handle + length.
-  // Needs the |field_trial_handle_switch| argument to be passed in since base/
-  // can't depend on content/.
-  static void CopyFieldTrialStateToFlags(const char* field_trial_handle_switch,
-                                         const char* enable_features_switch,
-                                         const char* disable_features_switch,
-                                         base::CommandLine* cmd_line);
-
-  // Create a FieldTrial with the given |name| and using 100% probability for
-  // the FieldTrial, force FieldTrial to have the same group string as
-  // |group_name|. This is commonly used in a non-browser process, to carry
-  // randomly selected state in a browser process into this non-browser process.
-  // It returns NULL if there is a FieldTrial that is already registered with
-  // the same |name| but has different finalized group string (|group_name|).
-  static FieldTrial* CreateFieldTrial(const std::string& name,
-                                      const std::string& group_name);
-
-  // Add an observer to be notified when a field trial is irrevocably committed
-  // to being part of some specific field_group (and hence the group_name is
-  // also finalized for that field_trial). Returns false and does nothing if
-  // there is no FieldTrialList singleton.
-  static bool AddObserver(Observer* observer);
-
-  // Remove an observer.
-  static void RemoveObserver(Observer* observer);
-
-  // Similar to AddObserver(), but the passed observer will be notified
-  // synchronously when a field trial is activated and its group selected. It
-  // will be notified synchronously on the same thread where the activation and
-  // group selection happened. It is the responsibility of the observer to make
-  // sure that this is a safe operation and the operation must be fast, as this
-  // work is done synchronously as part of group() or related APIs. Only a
-  // single such observer is supported, exposed specifically for crash
-  // reporting. Must be called on the main thread before any other threads
-  // have been started.
-  static void SetSynchronousObserver(Observer* observer);
-
-  // Removes the single synchronous observer.
-  static void RemoveSynchronousObserver(Observer* observer);
-
-  // Grabs the lock if necessary and adds the field trial to the allocator. This
-  // should only be called from FinalizeGroupChoice().
-  static void OnGroupFinalized(bool is_locked, FieldTrial* field_trial);
-
-  // Notify all observers that a group has been finalized for |field_trial|.
-  static void NotifyFieldTrialGroupSelection(FieldTrial* field_trial);
-
-  // Return the number of active field trials.
-  static size_t GetFieldTrialCount();
-
-  // Gets the parameters for |field_trial| from shared memory and stores them in
-  // |params|. This is only exposed for use by FieldTrialParamAssociator and
-  // shouldn't be used by anything else.
-  static bool GetParamsFromSharedMemory(
-      FieldTrial* field_trial,
-      std::map<std::string, std::string>* params);
-
-  // Clears all the params in the allocator.
-  static void ClearParamsFromSharedMemoryForTesting();
-
-  // Dumps field trial state to an allocator so that it can be analyzed after a
-  // crash.
-  static void DumpAllFieldTrialsToPersistentAllocator(
-      PersistentMemoryAllocator* allocator);
-
-  // Retrieves field trial state from an allocator so that it can be analyzed
-  // after a crash. The pointers in the returned vector are into the persistent
-  // memory segment and so are only valid as long as the allocator is valid.
-  static std::vector<const FieldTrial::FieldTrialEntry*>
-  GetAllFieldTrialsFromPersistentAllocator(
-      PersistentMemoryAllocator const& allocator);
-
-  // Returns true if a global field trial list is set. Only used for testing.
-  static bool IsGlobalSetForTesting();
-
- private:
-  // Allow tests to access our innards for testing purposes.
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, InstantiateAllocator);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, AddTrialsToAllocator);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest,
-                           DoNotAddSimulatedFieldTrialsToAllocator);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, AssociateFieldTrialParams);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, ClearParamsFromSharedMemory);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest,
-                           SerializeSharedMemoryHandleMetadata);
-  FRIEND_TEST_ALL_PREFIXES(FieldTrialListTest, CheckReadOnlySharedMemoryHandle);
-
-  // Serialization is used to pass information about the handle to child
-  // processes. It passes a reference to the relevant OS resource, and it passes
-  // a GUID. Serialization and deserialization doesn't actually transport the
-  // underlying OS resource - that must be done by the Process launcher.
-  static std::string SerializeSharedMemoryHandleMetadata(
-      const SharedMemoryHandle& shm);
-#if defined(OS_WIN) || defined(OS_FUCHSIA)
-  static SharedMemoryHandle DeserializeSharedMemoryHandleMetadata(
-      const std::string& switch_value);
-#elif defined(OS_POSIX) && !defined(OS_NACL)
-  static SharedMemoryHandle DeserializeSharedMemoryHandleMetadata(
-      int fd,
-      const std::string& switch_value);
-#endif
-
-#if defined(OS_WIN) || defined(OS_FUCHSIA)
-  // Takes in |handle_switch| from the command line which represents the shared
-  // memory handle for field trials, parses it, and creates the field trials.
-  // Returns true on success, false on failure.
-  // |switch_value| also contains the serialized GUID.
-  static bool CreateTrialsFromSwitchValue(const std::string& switch_value);
-#elif defined(OS_POSIX) && !defined(OS_NACL)
-  // On POSIX systems that use the zygote, we look up the correct fd that backs
-  // the shared memory segment containing the field trials by looking it up via
-  // an fd key in GlobalDescriptors. Returns true on success, false on failure.
-  // |switch_value| also contains the serialized GUID.
-  static bool CreateTrialsFromDescriptor(int fd_key,
-                                         const std::string& switch_value);
-#endif
-
-  // Takes an unmapped SharedMemoryHandle, creates a SharedMemory object from it
-  // and maps it with the correct size.
-  static bool CreateTrialsFromSharedMemoryHandle(SharedMemoryHandle shm_handle);
-
-  // Expects a mapped piece of shared memory |shm| that was created from the
-  // browser process's field_trial_allocator and shared via the command line.
-  // This function recreates the allocator, iterates through all the field
-  // trials in it, and creates them via CreateFieldTrial(). Returns true if
-  // successful and false otherwise.
-  static bool CreateTrialsFromSharedMemory(
-      std::unique_ptr<base::SharedMemory> shm);
-
-  // Instantiate the field trial allocator, add all existing field trials to it,
-  // and duplicates its handle to a read-only handle, which gets stored in
-  // |readonly_allocator_handle|.
-  static void InstantiateFieldTrialAllocatorIfNeeded();
-
-  // Adds the field trial to the allocator. Caller must hold a lock before
-  // calling this.
-  static void AddToAllocatorWhileLocked(PersistentMemoryAllocator* allocator,
-                                        FieldTrial* field_trial);
-
-  // Activate the corresponding field trial entry struct in shared memory.
-  static void ActivateFieldTrialEntryWhileLocked(FieldTrial* field_trial);
-
-  // A map from FieldTrial names to the actual instances.
-  typedef std::map<std::string, FieldTrial*> RegistrationMap;
-
-  // If one-time randomization is enabled, returns a weak pointer to the
-  // corresponding EntropyProvider. Otherwise, returns NULL.
-  static const FieldTrial::EntropyProvider*
-      GetEntropyProviderForOneTimeRandomization();
-
-  // Helper function should be called only while holding lock_.
-  FieldTrial* PreLockedFind(const std::string& name);
-
-  // Register() stores a pointer to the given trial in a global map.
-  // This method also AddRef's the indicated trial.
-  // This should always be called after creating a new FieldTrial instance.
-  static void Register(FieldTrial* trial);
-
-  // Returns all the registered trials.
-  static RegistrationMap GetRegisteredTrials();
-
-  static FieldTrialList* global_;  // The singleton of this class.
-
-  // This will tell us if there is an attempt to register a field
-  // trial or check if one-time randomization is enabled without
-  // creating the FieldTrialList. This is not an error, unless a
-  // FieldTrialList is created after that.
-  static bool used_without_global_;
-
-  // Lock for access to registered_ and field_trial_allocator_.
-  Lock lock_;
-  RegistrationMap registered_;
-
-  std::map<std::string, std::string> seen_states_;
-
-  // Entropy provider to be used for one-time randomized field trials. If NULL,
-  // one-time randomization is not supported.
-  std::unique_ptr<const FieldTrial::EntropyProvider> entropy_provider_;
-
-  // List of observers to be notified when a group is selected for a FieldTrial.
-  scoped_refptr<ObserverListThreadSafe<Observer> > observer_list_;
-
-  // Single synchronous observer to be notified when a trial group is chosen.
-  Observer* synchronous_observer_ = nullptr;
-
-  // Allocator in shared memory containing field trial data. Used in both
-  // browser and child processes, but readonly in the child.
-  // In the future, we may want to move this to a more generic place if we want
-  // to start passing more data other than field trials.
-  std::unique_ptr<FieldTrialAllocator> field_trial_allocator_ = nullptr;
-
-  // Readonly copy of the handle to the allocator. Needs to be a member variable
-  // because it's needed from both CopyFieldTrialStateToFlags() and
-  // AppendFieldTrialHandleIfNeeded().
-  base::SharedMemoryHandle readonly_allocator_handle_;
-
-  // Tracks whether CreateTrialsFromCommandLine() has been called.
-  bool create_trials_from_command_line_called_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(FieldTrialList);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_FIELD_TRIAL_H_
diff --git a/base/metrics/field_trial_param_associator.cc b/base/metrics/field_trial_param_associator.cc
deleted file mode 100644
index af76eaf..0000000
--- a/base/metrics/field_trial_param_associator.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/field_trial_param_associator.h"
-
-#include "base/metrics/field_trial.h"
-
-namespace base {
-
-FieldTrialParamAssociator::FieldTrialParamAssociator() = default;
-FieldTrialParamAssociator::~FieldTrialParamAssociator() = default;
-
-// static
-FieldTrialParamAssociator* FieldTrialParamAssociator::GetInstance() {
-  return Singleton<FieldTrialParamAssociator,
-                   LeakySingletonTraits<FieldTrialParamAssociator>>::get();
-}
-
-bool FieldTrialParamAssociator::AssociateFieldTrialParams(
-    const std::string& trial_name,
-    const std::string& group_name,
-    const FieldTrialParams& params) {
-  if (FieldTrialList::IsTrialActive(trial_name))
-    return false;
-
-  AutoLock scoped_lock(lock_);
-  const FieldTrialKey key(trial_name, group_name);
-  if (ContainsKey(field_trial_params_, key))
-    return false;
-
-  field_trial_params_[key] = params;
-  return true;
-}
-
-bool FieldTrialParamAssociator::GetFieldTrialParams(
-    const std::string& trial_name,
-    FieldTrialParams* params) {
-  FieldTrial* field_trial = FieldTrialList::Find(trial_name);
-  if (!field_trial)
-    return false;
-
-  // First try the local map, falling back to getting it from shared memory.
-  if (GetFieldTrialParamsWithoutFallback(trial_name, field_trial->group_name(),
-                                         params)) {
-    return true;
-  }
-
-  // TODO(lawrencewu): add the params to field_trial_params_ for next time.
-  return FieldTrialList::GetParamsFromSharedMemory(field_trial, params);
-}
-
-bool FieldTrialParamAssociator::GetFieldTrialParamsWithoutFallback(
-    const std::string& trial_name,
-    const std::string& group_name,
-    FieldTrialParams* params) {
-  AutoLock scoped_lock(lock_);
-
-  const FieldTrialKey key(trial_name, group_name);
-  if (!ContainsKey(field_trial_params_, key))
-    return false;
-
-  *params = field_trial_params_[key];
-  return true;
-}
-
-void FieldTrialParamAssociator::ClearAllParamsForTesting() {
-  {
-    AutoLock scoped_lock(lock_);
-    field_trial_params_.clear();
-  }
-  FieldTrialList::ClearParamsFromSharedMemoryForTesting();
-}
-
-void FieldTrialParamAssociator::ClearParamsForTesting(
-    const std::string& trial_name,
-    const std::string& group_name) {
-  AutoLock scoped_lock(lock_);
-  const FieldTrialKey key(trial_name, group_name);
-  field_trial_params_.erase(key);
-}
-
-void FieldTrialParamAssociator::ClearAllCachedParamsForTesting() {
-  AutoLock scoped_lock(lock_);
-  field_trial_params_.clear();
-}
-
-}  // namespace base
diff --git a/base/metrics/field_trial_param_associator.h b/base/metrics/field_trial_param_associator.h
deleted file mode 100644
index b35e2cc..0000000
--- a/base/metrics/field_trial_param_associator.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_FIELD_TRIAL_PARAM_ASSOCIATOR_H_
-#define BASE_METRICS_FIELD_TRIAL_PARAM_ASSOCIATOR_H_
-
-#include <map>
-#include <string>
-#include <utility>
-
-#include "base/base_export.h"
-#include "base/memory/singleton.h"
-#include "base/metrics/field_trial.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-// Keeps track of the parameters of all field trials and ensures access to them
-// is thread-safe.
-class BASE_EXPORT FieldTrialParamAssociator {
- public:
-  FieldTrialParamAssociator();
-  ~FieldTrialParamAssociator();
-
-  // Key-value mapping type for field trial parameters.
-  typedef std::map<std::string, std::string> FieldTrialParams;
-
-  // Retrieve the singleton.
-  static FieldTrialParamAssociator* GetInstance();
-
-  // Sets parameters for the given field trial name and group.
-  bool AssociateFieldTrialParams(const std::string& trial_name,
-                                 const std::string& group_name,
-                                 const FieldTrialParams& params);
-
-  // Gets the parameters for a field trial and its chosen group. If not found in
-  // field_trial_params_, then tries to looks it up in shared memory.
-  bool GetFieldTrialParams(const std::string& trial_name,
-                           FieldTrialParams* params);
-
-  // Gets the parameters for a field trial and its chosen group. Does not
-  // fallback to looking it up in shared memory. This should only be used if you
-  // know for sure the params are in the mapping, like if you're in the browser
-  // process, and even then you should probably just use GetFieldTrialParams().
-  bool GetFieldTrialParamsWithoutFallback(const std::string& trial_name,
-                                          const std::string& group_name,
-                                          FieldTrialParams* params);
-
-  // Clears the internal field_trial_params_ mapping, plus removes all params in
-  // shared memory.
-  void ClearAllParamsForTesting();
-
-  // Clears a single field trial param.
-  // Note: this does NOT remove the param in shared memory.
-  void ClearParamsForTesting(const std::string& trial_name,
-                             const std::string& group_name);
-
-  // Clears the internal field_trial_params_ mapping.
-  void ClearAllCachedParamsForTesting();
-
- private:
-  friend struct DefaultSingletonTraits<FieldTrialParamAssociator>;
-
-  // (field_trial_name, field_trial_group)
-  typedef std::pair<std::string, std::string> FieldTrialKey;
-
-  Lock lock_;
-  std::map<FieldTrialKey, FieldTrialParams> field_trial_params_;
-
-  DISALLOW_COPY_AND_ASSIGN(FieldTrialParamAssociator);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_FIELD_TRIAL_PARAM_ASSOCIATOR_H_
diff --git a/base/metrics/field_trial_params.cc b/base/metrics/field_trial_params.cc
deleted file mode 100644
index 7195f4a..0000000
--- a/base/metrics/field_trial_params.cc
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/field_trial_params.h"
-
-#include "base/feature_list.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/field_trial_param_associator.h"
-#include "base/strings/string_number_conversions.h"
-
-namespace base {
-
-bool AssociateFieldTrialParams(
-    const std::string& trial_name,
-    const std::string& group_name,
-    const std::map<std::string, std::string>& params) {
-  return base::FieldTrialParamAssociator::GetInstance()
-      ->AssociateFieldTrialParams(trial_name, group_name, params);
-}
-
-bool GetFieldTrialParams(const std::string& trial_name,
-                         std::map<std::string, std::string>* params) {
-  return base::FieldTrialParamAssociator::GetInstance()->GetFieldTrialParams(
-      trial_name, params);
-}
-
-bool GetFieldTrialParamsByFeature(const base::Feature& feature,
-                                  std::map<std::string, std::string>* params) {
-  if (!base::FeatureList::IsEnabled(feature))
-    return false;
-
-  base::FieldTrial* trial = base::FeatureList::GetFieldTrial(feature);
-  if (!trial)
-    return false;
-
-  return GetFieldTrialParams(trial->trial_name(), params);
-}
-
-std::string GetFieldTrialParamValue(const std::string& trial_name,
-                                    const std::string& param_name) {
-  std::map<std::string, std::string> params;
-  if (GetFieldTrialParams(trial_name, &params)) {
-    std::map<std::string, std::string>::iterator it = params.find(param_name);
-    if (it != params.end())
-      return it->second;
-  }
-  return std::string();
-}
-
-std::string GetFieldTrialParamValueByFeature(const base::Feature& feature,
-                                             const std::string& param_name) {
-  if (!base::FeatureList::IsEnabled(feature))
-    return std::string();
-
-  base::FieldTrial* trial = base::FeatureList::GetFieldTrial(feature);
-  if (!trial)
-    return std::string();
-
-  return GetFieldTrialParamValue(trial->trial_name(), param_name);
-}
-
-int GetFieldTrialParamByFeatureAsInt(const base::Feature& feature,
-                                     const std::string& param_name,
-                                     int default_value) {
-  std::string value_as_string =
-      GetFieldTrialParamValueByFeature(feature, param_name);
-  int value_as_int = 0;
-  if (!base::StringToInt(value_as_string, &value_as_int)) {
-    if (!value_as_string.empty()) {
-      DLOG(WARNING) << "Failed to parse field trial param " << param_name
-                    << " with string value " << value_as_string
-                    << " under feature " << feature.name
-                    << " into an int. Falling back to default value of "
-                    << default_value;
-    }
-    value_as_int = default_value;
-  }
-  return value_as_int;
-}
-
-double GetFieldTrialParamByFeatureAsDouble(const base::Feature& feature,
-                                           const std::string& param_name,
-                                           double default_value) {
-  std::string value_as_string =
-      GetFieldTrialParamValueByFeature(feature, param_name);
-  double value_as_double = 0;
-  if (!base::StringToDouble(value_as_string, &value_as_double)) {
-    if (!value_as_string.empty()) {
-      DLOG(WARNING) << "Failed to parse field trial param " << param_name
-                    << " with string value " << value_as_string
-                    << " under feature " << feature.name
-                    << " into a double. Falling back to default value of "
-                    << default_value;
-    }
-    value_as_double = default_value;
-  }
-  return value_as_double;
-}
-
-bool GetFieldTrialParamByFeatureAsBool(const base::Feature& feature,
-                                       const std::string& param_name,
-                                       bool default_value) {
-  std::string value_as_string =
-      GetFieldTrialParamValueByFeature(feature, param_name);
-  if (value_as_string == "true")
-    return true;
-  if (value_as_string == "false")
-    return false;
-
-  if (!value_as_string.empty()) {
-    DLOG(WARNING) << "Failed to parse field trial param " << param_name
-                  << " with string value " << value_as_string
-                  << " under feature " << feature.name
-                  << " into a bool. Falling back to default value of "
-                  << default_value;
-  }
-  return default_value;
-}
-
-std::string FeatureParam<std::string>::Get() const {
-  const std::string value = GetFieldTrialParamValueByFeature(*feature, name);
-  return value.empty() ? default_value : value;
-}
-
-double FeatureParam<double>::Get() const {
-  return GetFieldTrialParamByFeatureAsDouble(*feature, name, default_value);
-}
-
-int FeatureParam<int>::Get() const {
-  return GetFieldTrialParamByFeatureAsInt(*feature, name, default_value);
-}
-
-bool FeatureParam<bool>::Get() const {
-  return GetFieldTrialParamByFeatureAsBool(*feature, name, default_value);
-}
-
-void LogInvalidEnumValue(const base::Feature& feature,
-                         const std::string& param_name,
-                         const std::string& value_as_string,
-                         int default_value_as_int) {
-  DLOG(WARNING) << "Failed to parse field trial param " << param_name
-                << " with string value " << value_as_string << " under feature "
-                << feature.name
-                << " into an enum. Falling back to default value of "
-                << default_value_as_int;
-}
-
-}  // namespace base
diff --git a/base/metrics/field_trial_params.h b/base/metrics/field_trial_params.h
deleted file mode 100644
index 8682226..0000000
--- a/base/metrics/field_trial_params.h
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_FIELD_TRIAL_PARAMS_H_
-#define BASE_METRICS_FIELD_TRIAL_PARAMS_H_
-
-#include <map>
-#include <string>
-
-#include "base/base_export.h"
-
-namespace base {
-
-struct Feature;
-
-// Associates the specified set of key-value |params| with the field trial
-// specified by |trial_name| and |group_name|. Fails and returns false if the
-// specified field trial already has params associated with it or the trial
-// is already active (group() has been called on it). Thread safe.
-BASE_EXPORT bool AssociateFieldTrialParams(
-    const std::string& trial_name,
-    const std::string& group_name,
-    const std::map<std::string, std::string>& params);
-
-// Retrieves the set of key-value |params| for the specified field trial, based
-// on its selected group. If the field trial does not exist or its selected
-// group does not have any parameters associated with it, returns false and
-// does not modify |params|. Calling this function will result in the field
-// trial being marked as active if found (i.e. group() will be called on it),
-// if it wasn't already. Thread safe.
-BASE_EXPORT bool GetFieldTrialParams(
-    const std::string& trial_name,
-    std::map<std::string, std::string>* params);
-
-// Retrieves the set of key-value |params| for the field trial associated with
-// the specified |feature|. A feature is associated with at most one field
-// trial and selected group. See  base/feature_list.h for more information on
-// features. If the feature is not enabled, or if there's no associated params,
-// returns false and does not modify |params|. Calling this function will
-// result in the associated field trial being marked as active if found (i.e.
-// group() will be called on it), if it wasn't already. Thread safe.
-BASE_EXPORT bool GetFieldTrialParamsByFeature(
-    const base::Feature& feature,
-    std::map<std::string, std::string>* params);
-
-// Retrieves a specific parameter value corresponding to |param_name| for the
-// specified field trial, based on its selected group. If the field trial does
-// not exist or the specified parameter does not exist, returns an empty
-// string. Calling this function will result in the field trial being marked as
-// active if found (i.e. group() will be called on it), if it wasn't already.
-// Thread safe.
-BASE_EXPORT std::string GetFieldTrialParamValue(const std::string& trial_name,
-                                                const std::string& param_name);
-
-// Retrieves a specific parameter value corresponding to |param_name| for the
-// field trial associated with the specified |feature|. A feature is associated
-// with at most one field trial and selected group. See base/feature_list.h for
-// more information on features. If the feature is not enabled, or the
-// specified parameter does not exist, returns an empty string. Calling this
-// function will result in the associated field trial being marked as active if
-// found (i.e. group() will be called on it), if it wasn't already. Thread safe.
-BASE_EXPORT std::string GetFieldTrialParamValueByFeature(
-    const base::Feature& feature,
-    const std::string& param_name);
-
-// Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the
-// string value into an int using base::StringToInt() and returns it, if
-// successful. Otherwise, it returns |default_value|. If the string value is not
-// empty and the conversion does not succeed, it produces a warning to LOG.
-BASE_EXPORT int GetFieldTrialParamByFeatureAsInt(const base::Feature& feature,
-                                                 const std::string& param_name,
-                                                 int default_value);
-
-// Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the
-// string value into a double using base::StringToDouble() and returns it, if
-// successful. Otherwise, it returns |default_value|. If the string value is not
-// empty and the conversion does not succeed, it produces a warning to LOG.
-BASE_EXPORT double GetFieldTrialParamByFeatureAsDouble(
-    const base::Feature& feature,
-    const std::string& param_name,
-    double default_value);
-
-// Same as GetFieldTrialParamValueByFeature(). On top of that, it converts the
-// string value into a boolean and returns it, if successful. Otherwise, it
-// returns |default_value|. The only string representations accepted here are
-// "true" and "false". If the string value is not empty and the conversion does
-// not succeed, it produces a warning to LOG.
-BASE_EXPORT bool GetFieldTrialParamByFeatureAsBool(
-    const base::Feature& feature,
-    const std::string& param_name,
-    bool default_value);
-
-// Shared declaration for various FeatureParam<T> types.
-//
-// This template is defined for the following types T:
-//   bool
-//   int
-//   double
-//   std::string
-//   enum types
-//
-// See the individual definitions below for the appropriate interfaces.
-// Attempting to use it with any other type is a compile error.
-template <typename T, bool IsEnum = std::is_enum<T>::value>
-struct FeatureParam {
-  // Prevent use of FeatureParam<> with unsupported types (e.g. void*). Uses T
-  // in its definition so that evaluation is deferred until the template is
-  // instantiated.
-  static_assert(!std::is_same<T, T>::value, "unsupported FeatureParam<> type");
-};
-
-// Declares a string-valued parameter. Example:
-//
-//     constexpr FeatureParam<string> kAssistantName{
-//         &kAssistantFeature, "assistant_name", "HAL"};
-//
-// If the feature is not set, or set to the empty string, then Get() will return
-// the default value.
-template <>
-struct FeatureParam<std::string> {
-  constexpr FeatureParam(const Feature* feature,
-                         const char* name,
-                         const char* default_value)
-      : feature(feature), name(name), default_value(default_value) {}
-
-  BASE_EXPORT std::string Get() const;
-
-  const Feature* const feature;
-  const char* const name;
-  const char* const default_value;
-};
-
-// Declares a double-valued parameter. Example:
-//
-//     constexpr FeatureParam<double> kAssistantTriggerThreshold{
-//         &kAssistantFeature, "trigger_threshold", 0.10};
-//
-// If the feature is not set, or set to an invalid double value, then Get() will
-// return the default value.
-template <>
-struct FeatureParam<double> {
-  constexpr FeatureParam(const Feature* feature,
-                         const char* name,
-                         double default_value)
-      : feature(feature), name(name), default_value(default_value) {}
-
-  BASE_EXPORT double Get() const;
-
-  const Feature* const feature;
-  const char* const name;
-  const double default_value;
-};
-
-// Declares an int-valued parameter. Example:
-//
-//     constexpr FeatureParam<int> kAssistantParallelism{
-//         &kAssistantFeature, "parallelism", 4};
-//
-// If the feature is not set, or set to an invalid int value, then Get() will
-// return the default value.
-template <>
-struct FeatureParam<int> {
-  constexpr FeatureParam(const Feature* feature,
-                         const char* name,
-                         int default_value)
-      : feature(feature), name(name), default_value(default_value) {}
-
-  BASE_EXPORT int Get() const;
-
-  const Feature* const feature;
-  const char* const name;
-  const int default_value;
-};
-
-// Declares a bool-valued parameter. Example:
-//
-//     constexpr FeatureParam<int> kAssistantIsHelpful{
-//         &kAssistantFeature, "is_helpful", true};
-//
-// If the feature is not set, or set to value other than "true" or "false", then
-// Get() will return the default value.
-template <>
-struct FeatureParam<bool> {
-  constexpr FeatureParam(const Feature* feature,
-                         const char* name,
-                         bool default_value)
-      : feature(feature), name(name), default_value(default_value) {}
-
-  BASE_EXPORT bool Get() const;
-
-  const Feature* const feature;
-  const char* const name;
-  const bool default_value;
-};
-
-BASE_EXPORT void LogInvalidEnumValue(const Feature& feature,
-                                     const std::string& param_name,
-                                     const std::string& value_as_string,
-                                     int default_value_as_int);
-
-// Feature param declaration for an enum, with associated options. Example:
-//
-//     constexpr FeatureParam<ShapeEnum>::Option[] kShapeParamOptions[] = {
-//         {SHAPE_CIRCLE, "circle"},
-//         {SHAPE_CYLINDER, "cylinder"},
-//         {SHAPE_PAPERCLIP, "paperclip"}};
-//     constexpr FeatureParam<ShapeEnum> kAssistantShapeParam{
-//         &kAssistantFeature, "shape", SHAPE_CIRCLE, &kShapeParamOptions};
-//
-// With this declaration, the parameter may be set to "circle", "cylinder", or
-// "paperclip", and that will be translated to one of the three enum values. By
-// default, or if the param is set to an unknown value, the parameter will be
-// assumed to be SHAPE_CIRCLE.
-template <typename Enum>
-struct FeatureParam<Enum, true> {
-  struct Option {
-    constexpr Option(Enum value, const char* name) : value(value), name(name) {}
-
-    const Enum value;
-    const char* const name;
-  };
-
-  template <size_t option_count>
-  constexpr FeatureParam(const Feature* feature,
-                         const char* name,
-                         const Enum default_value,
-                         const Option (*options)[option_count])
-      : feature(feature),
-        name(name),
-        default_value(default_value),
-        options(*options),
-        option_count(option_count) {
-    static_assert(option_count >= 1, "FeatureParam<enum> has no options");
-  }
-
-  Enum Get() const {
-    std::string value = GetFieldTrialParamValueByFeature(*feature, name);
-    if (value.empty())
-      return default_value;
-    for (size_t i = 0; i < option_count; ++i) {
-      if (value == options[i].name)
-        return options[i].value;
-    }
-    LogInvalidEnumValue(*feature, name, value, static_cast<int>(default_value));
-    return default_value;
-  }
-
-  const base::Feature* const feature;
-  const char* const name;
-  const Enum default_value;
-  const Option* const options;
-  const size_t option_count;
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_FIELD_TRIAL_PARAMS_H_
diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
deleted file mode 100644
index 07e09cf..0000000
--- a/base/metrics/histogram.cc
+++ /dev/null
@@ -1,1315 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Histogram is an object that aggregates statistics, and can summarize them in
-// various forms, including ASCII graphical, HTML, and numerically (as a
-// vector of numbers corresponding to each of the aggregating buckets).
-// See header file for details and examples.
-
-#include "base/metrics/histogram.h"
-
-#include <inttypes.h>
-#include <limits.h>
-#include <math.h>
-
-#include <algorithm>
-#include <string>
-#include <utility>
-
-#include "base/compiler_specific.h"
-#include "base/debug/alias.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/dummy_histogram.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/metrics_hashes.h"
-#include "base/metrics/persistent_histogram_allocator.h"
-#include "base/metrics/persistent_memory_allocator.h"
-#include "base/metrics/sample_vector.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/pickle.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/lock.h"
-#include "base/sys_info.h"
-#include "base/values.h"
-#include "build_config.h"
-
-namespace base {
-
-namespace {
-
-bool ReadHistogramArguments(PickleIterator* iter,
-                            std::string* histogram_name,
-                            int* flags,
-                            int* declared_min,
-                            int* declared_max,
-                            uint32_t* bucket_count,
-                            uint32_t* range_checksum) {
-  if (!iter->ReadString(histogram_name) ||
-      !iter->ReadInt(flags) ||
-      !iter->ReadInt(declared_min) ||
-      !iter->ReadInt(declared_max) ||
-      !iter->ReadUInt32(bucket_count) ||
-      !iter->ReadUInt32(range_checksum)) {
-    DLOG(ERROR) << "Pickle error decoding Histogram: " << *histogram_name;
-    return false;
-  }
-
-  // Since these fields may have come from an untrusted renderer, do additional
-  // checks above and beyond those in Histogram::Initialize()
-  if (*declared_max <= 0 ||
-      *declared_min <= 0 ||
-      *declared_max < *declared_min ||
-      INT_MAX / sizeof(HistogramBase::Count) <= *bucket_count ||
-      *bucket_count < 2) {
-    DLOG(ERROR) << "Values error decoding Histogram: " << histogram_name;
-    return false;
-  }
-
-  // We use the arguments to find or create the local version of the histogram
-  // in this process, so we need to clear any IPC flag.
-  *flags &= ~HistogramBase::kIPCSerializationSourceFlag;
-
-  return true;
-}
-
-bool ValidateRangeChecksum(const HistogramBase& histogram,
-                           uint32_t range_checksum) {
-  // Normally, |histogram| should have type HISTOGRAM or be inherited from it.
-  // However, if it's expired, it will actually be a DUMMY_HISTOGRAM.
-  // Skip the checks in that case.
-  if (histogram.GetHistogramType() == DUMMY_HISTOGRAM)
-    return true;
-  const Histogram& casted_histogram =
-      static_cast<const Histogram&>(histogram);
-
-  return casted_histogram.bucket_ranges()->checksum() == range_checksum;
-}
-
-}  // namespace
-
-typedef HistogramBase::Count Count;
-typedef HistogramBase::Sample Sample;
-
-// static
-const uint32_t Histogram::kBucketCount_MAX = 16384u;
-
-class Histogram::Factory {
- public:
-  Factory(const std::string& name,
-          HistogramBase::Sample minimum,
-          HistogramBase::Sample maximum,
-          uint32_t bucket_count,
-          int32_t flags)
-    : Factory(name, HISTOGRAM, minimum, maximum, bucket_count, flags) {}
-
-  // Create histogram based on construction parameters. Caller takes
-  // ownership of the returned object.
-  HistogramBase* Build();
-
- protected:
-  Factory(const std::string& name,
-          HistogramType histogram_type,
-          HistogramBase::Sample minimum,
-          HistogramBase::Sample maximum,
-          uint32_t bucket_count,
-          int32_t flags)
-    : name_(name),
-      histogram_type_(histogram_type),
-      minimum_(minimum),
-      maximum_(maximum),
-      bucket_count_(bucket_count),
-      flags_(flags) {}
-
-  // Create a BucketRanges structure appropriate for this histogram.
-  virtual BucketRanges* CreateRanges() {
-    BucketRanges* ranges = new BucketRanges(bucket_count_ + 1);
-    Histogram::InitializeBucketRanges(minimum_, maximum_, ranges);
-    return ranges;
-  }
-
-  // Allocate the correct Histogram object off the heap (in case persistent
-  // memory is not available).
-  virtual std::unique_ptr<HistogramBase> HeapAlloc(const BucketRanges* ranges) {
-    return WrapUnique(
-        new Histogram(GetPermanentName(name_), minimum_, maximum_, ranges));
-  }
-
-  // Perform any required datafill on the just-created histogram.  If
-  // overridden, be sure to call the "super" version -- this method may not
-  // always remain empty.
-  virtual void FillHistogram(HistogramBase* histogram) {}
-
-  // These values are protected (instead of private) because they need to
-  // be accessible to methods of sub-classes in order to avoid passing
-  // unnecessary parameters everywhere.
-  const std::string& name_;
-  const HistogramType histogram_type_;
-  HistogramBase::Sample minimum_;
-  HistogramBase::Sample maximum_;
-  uint32_t bucket_count_;
-  int32_t flags_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Factory);
-};
-
-HistogramBase* Histogram::Factory::Build() {
-  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_);
-  if (!histogram) {
-    // TODO(gayane): |HashMetricName()| is called again in Histogram
-    // constructor. Refactor code to avoid the additional call.
-    bool should_record =
-        StatisticsRecorder::ShouldRecordHistogram(HashMetricName(name_));
-    if (!should_record)
-      return DummyHistogram::GetInstance();
-    // To avoid racy destruction at shutdown, the following will be leaked.
-    const BucketRanges* created_ranges = CreateRanges();
-    const BucketRanges* registered_ranges =
-        StatisticsRecorder::RegisterOrDeleteDuplicateRanges(created_ranges);
-
-    // In most cases, the bucket-count, minimum, and maximum values are known
-    // when the code is written and so are passed in explicitly. In other
-    // cases (such as with a CustomHistogram), they are calculated dynamically
-    // at run-time. In the latter case, those ctor parameters are zero and
-    // the results extracted from the result of CreateRanges().
-    if (bucket_count_ == 0) {
-      bucket_count_ = static_cast<uint32_t>(registered_ranges->bucket_count());
-      minimum_ = registered_ranges->range(1);
-      maximum_ = registered_ranges->range(bucket_count_ - 1);
-    }
-    DCHECK_EQ(minimum_, registered_ranges->range(1));
-    DCHECK_EQ(maximum_, registered_ranges->range(bucket_count_ - 1));
-
-    // Try to create the histogram using a "persistent" allocator. As of
-    // 2016-02-25, the availability of such is controlled by a base::Feature
-    // that is off by default. If the allocator doesn't exist or if
-    // allocating from it fails, code below will allocate the histogram from
-    // the process heap.
-    PersistentHistogramAllocator::Reference histogram_ref = 0;
-    std::unique_ptr<HistogramBase> tentative_histogram;
-    PersistentHistogramAllocator* allocator = GlobalHistogramAllocator::Get();
-    if (allocator) {
-      tentative_histogram = allocator->AllocateHistogram(
-          histogram_type_,
-          name_,
-          minimum_,
-          maximum_,
-          registered_ranges,
-          flags_,
-          &histogram_ref);
-    }
-
-    // Handle the case where no persistent allocator is present or the
-    // persistent allocation fails (perhaps because it is full).
-    if (!tentative_histogram) {
-      DCHECK(!histogram_ref);  // Should never have been set.
-      DCHECK(!allocator);  // Shouldn't have failed.
-      flags_ &= ~HistogramBase::kIsPersistent;
-      tentative_histogram = HeapAlloc(registered_ranges);
-      tentative_histogram->SetFlags(flags_);
-    }
-
-    FillHistogram(tentative_histogram.get());
-
-    // Register this histogram with the StatisticsRecorder. Keep a copy of
-    // the pointer value to tell later whether the locally created histogram
-    // was registered or deleted. The type is "void" because it could point
-    // to released memory after the following line.
-    const void* tentative_histogram_ptr = tentative_histogram.get();
-    histogram = StatisticsRecorder::RegisterOrDeleteDuplicate(
-        tentative_histogram.release());
-
-    // Persistent histograms need some follow-up processing.
-    if (histogram_ref) {
-      allocator->FinalizeHistogram(histogram_ref,
-                                   histogram == tentative_histogram_ptr);
-    }
-  }
-
-  if (histogram_type_ != histogram->GetHistogramType() ||
-      (bucket_count_ != 0 && !histogram->HasConstructionArguments(
-                                 minimum_, maximum_, bucket_count_))) {
-    // The construction arguments do not match the existing histogram.  This can
-    // come about if an extension updates in the middle of a chrome run and has
-    // changed one of them, or simply by bad code within Chrome itself.  A NULL
-    // return would cause Chrome to crash; better to just record it for later
-    // analysis.
-    UmaHistogramSparse("Histogram.MismatchedConstructionArguments",
-                       static_cast<Sample>(HashMetricName(name_)));
-    DLOG(ERROR) << "Histogram " << name_
-                << " has mismatched construction arguments";
-    return DummyHistogram::GetInstance();
-  }
-  return histogram;
-}
-
-HistogramBase* Histogram::FactoryGet(const std::string& name,
-                                     Sample minimum,
-                                     Sample maximum,
-                                     uint32_t bucket_count,
-                                     int32_t flags) {
-  bool valid_arguments =
-      InspectConstructionArguments(name, &minimum, &maximum, &bucket_count);
-  DCHECK(valid_arguments);
-
-  return Factory(name, minimum, maximum, bucket_count, flags).Build();
-}
-
-HistogramBase* Histogram::FactoryTimeGet(const std::string& name,
-                                         TimeDelta minimum,
-                                         TimeDelta maximum,
-                                         uint32_t bucket_count,
-                                         int32_t flags) {
-  return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()),
-                    static_cast<Sample>(maximum.InMilliseconds()), bucket_count,
-                    flags);
-}
-
-HistogramBase* Histogram::FactoryMicrosecondsTimeGet(const std::string& name,
-                                                     TimeDelta minimum,
-                                                     TimeDelta maximum,
-                                                     uint32_t bucket_count,
-                                                     int32_t flags) {
-  return FactoryGet(name, static_cast<Sample>(minimum.InMicroseconds()),
-                    static_cast<Sample>(maximum.InMicroseconds()), bucket_count,
-                    flags);
-}
-
-HistogramBase* Histogram::FactoryGet(const char* name,
-                                     Sample minimum,
-                                     Sample maximum,
-                                     uint32_t bucket_count,
-                                     int32_t flags) {
-  return FactoryGet(std::string(name), minimum, maximum, bucket_count, flags);
-}
-
-HistogramBase* Histogram::FactoryTimeGet(const char* name,
-                                         TimeDelta minimum,
-                                         TimeDelta maximum,
-                                         uint32_t bucket_count,
-                                         int32_t flags) {
-  return FactoryTimeGet(std::string(name), minimum, maximum, bucket_count,
-                        flags);
-}
-
-HistogramBase* Histogram::FactoryMicrosecondsTimeGet(const char* name,
-                                                     TimeDelta minimum,
-                                                     TimeDelta maximum,
-                                                     uint32_t bucket_count,
-                                                     int32_t flags) {
-  return FactoryMicrosecondsTimeGet(std::string(name), minimum, maximum,
-                                    bucket_count, flags);
-}
-
-std::unique_ptr<HistogramBase> Histogram::PersistentCreate(
-    const char* name,
-    Sample minimum,
-    Sample maximum,
-    const BucketRanges* ranges,
-    const DelayedPersistentAllocation& counts,
-    const DelayedPersistentAllocation& logged_counts,
-    HistogramSamples::Metadata* meta,
-    HistogramSamples::Metadata* logged_meta) {
-  return WrapUnique(new Histogram(name, minimum, maximum, ranges, counts,
-                                  logged_counts, meta, logged_meta));
-}
-
-// Calculate what range of values are held in each bucket.
-// We have to be careful that we don't pick a ratio between starting points in
-// consecutive buckets that is sooo small, that the integer bounds are the same
-// (effectively making one bucket get no values).  We need to avoid:
-//   ranges(i) == ranges(i + 1)
-// To avoid that, we just do a fine-grained bucket width as far as we need to
-// until we get a ratio that moves us along at least 2 units at a time.  From
-// that bucket onward we do use the exponential growth of buckets.
-//
-// static
-void Histogram::InitializeBucketRanges(Sample minimum,
-                                       Sample maximum,
-                                       BucketRanges* ranges) {
-  double log_max = log(static_cast<double>(maximum));
-  double log_ratio;
-  double log_next;
-  size_t bucket_index = 1;
-  Sample current = minimum;
-  ranges->set_range(bucket_index, current);
-  size_t bucket_count = ranges->bucket_count();
-  while (bucket_count > ++bucket_index) {
-    double log_current;
-    log_current = log(static_cast<double>(current));
-    // Calculate the count'th root of the range.
-    log_ratio = (log_max - log_current) / (bucket_count - bucket_index);
-    // See where the next bucket would start.
-    log_next = log_current + log_ratio;
-    Sample next;
-    next = static_cast<int>(std::round(exp(log_next)));
-    if (next > current)
-      current = next;
-    else
-      ++current;  // Just do a narrow bucket, and keep trying.
-    ranges->set_range(bucket_index, current);
-  }
-  ranges->set_range(ranges->bucket_count(), HistogramBase::kSampleType_MAX);
-  ranges->ResetChecksum();
-}
-
-// static
-const int Histogram::kCommonRaceBasedCountMismatch = 5;
-
-uint32_t Histogram::FindCorruption(const HistogramSamples& samples) const {
-  int inconsistencies = NO_INCONSISTENCIES;
-  Sample previous_range = -1;  // Bottom range is always 0.
-  for (uint32_t index = 0; index < bucket_count(); ++index) {
-    int new_range = ranges(index);
-    if (previous_range >= new_range)
-      inconsistencies |= BUCKET_ORDER_ERROR;
-    previous_range = new_range;
-  }
-
-  if (!bucket_ranges()->HasValidChecksum())
-    inconsistencies |= RANGE_CHECKSUM_ERROR;
-
-  int64_t delta64 = samples.redundant_count() - samples.TotalCount();
-  if (delta64 != 0) {
-    int delta = static_cast<int>(delta64);
-    if (delta != delta64)
-      delta = INT_MAX;  // Flag all giant errors as INT_MAX.
-    if (delta > 0) {
-      if (delta > kCommonRaceBasedCountMismatch)
-        inconsistencies |= COUNT_HIGH_ERROR;
-    } else {
-      DCHECK_GT(0, delta);
-      if (-delta > kCommonRaceBasedCountMismatch)
-        inconsistencies |= COUNT_LOW_ERROR;
-    }
-  }
-  return inconsistencies;
-}
-
-const BucketRanges* Histogram::bucket_ranges() const {
-  return unlogged_samples_->bucket_ranges();
-}
-
-Sample Histogram::declared_min() const {
-  const BucketRanges* ranges = bucket_ranges();
-  if (ranges->bucket_count() < 2)
-    return -1;
-  return ranges->range(1);
-}
-
-Sample Histogram::declared_max() const {
-  const BucketRanges* ranges = bucket_ranges();
-  if (ranges->bucket_count() < 2)
-    return -1;
-  return ranges->range(ranges->bucket_count() - 1);
-}
-
-Sample Histogram::ranges(uint32_t i) const {
-  return bucket_ranges()->range(i);
-}
-
-uint32_t Histogram::bucket_count() const {
-  return static_cast<uint32_t>(bucket_ranges()->bucket_count());
-}
-
-// static
-bool Histogram::InspectConstructionArguments(StringPiece name,
-                                             Sample* minimum,
-                                             Sample* maximum,
-                                             uint32_t* bucket_count) {
-  // Defensive code for backward compatibility.
-  if (*minimum < 1) {
-    DVLOG(1) << "Histogram: " << name << " has bad minimum: " << *minimum;
-    *minimum = 1;
-  }
-  if (*maximum >= kSampleType_MAX) {
-    DVLOG(1) << "Histogram: " << name << " has bad maximum: " << *maximum;
-    *maximum = kSampleType_MAX - 1;
-  }
-  if (*bucket_count >= kBucketCount_MAX) {
-    DVLOG(1) << "Histogram: " << name << " has bad bucket_count: "
-             << *bucket_count;
-    *bucket_count = kBucketCount_MAX - 1;
-  }
-
-  bool check_okay = true;
-
-  if (*minimum > *maximum) {
-    check_okay = false;
-    std::swap(*minimum, *maximum);
-  }
-  if (*maximum == *minimum) {
-    check_okay = false;
-    *maximum = *minimum + 1;
-  }
-  if (*bucket_count < 3) {
-    check_okay = false;
-    *bucket_count = 3;
-  }
-  // Very high bucket counts are wasteful. Use a sparse histogram instead.
-  // Value of 10002 equals a user-supplied value of 10k + 2 overflow buckets.
-  constexpr uint32_t kMaxBucketCount = 10002;
-  if (*bucket_count > kMaxBucketCount) {
-    check_okay = false;
-    *bucket_count = kMaxBucketCount;
-  }
-  if (*bucket_count > static_cast<uint32_t>(*maximum - *minimum + 2)) {
-    check_okay = false;
-    *bucket_count = static_cast<uint32_t>(*maximum - *minimum + 2);
-  }
-
-  if (!check_okay) {
-    UmaHistogramSparse("Histogram.BadConstructionArguments",
-                       static_cast<Sample>(HashMetricName(name)));
-  }
-
-  return check_okay;
-}
-
-uint64_t Histogram::name_hash() const {
-  return unlogged_samples_->id();
-}
-
-HistogramType Histogram::GetHistogramType() const {
-  return HISTOGRAM;
-}
-
-bool Histogram::HasConstructionArguments(Sample expected_minimum,
-                                         Sample expected_maximum,
-                                         uint32_t expected_bucket_count) const {
-  return (expected_bucket_count == bucket_count() &&
-          expected_minimum == declared_min() &&
-          expected_maximum == declared_max());
-}
-
-void Histogram::Add(int value) {
-  AddCount(value, 1);
-}
-
-void Histogram::AddCount(int value, int count) {
-  DCHECK_EQ(0, ranges(0));
-  DCHECK_EQ(kSampleType_MAX, ranges(bucket_count()));
-
-  if (value > kSampleType_MAX - 1)
-    value = kSampleType_MAX - 1;
-  if (value < 0)
-    value = 0;
-  if (count <= 0) {
-    NOTREACHED();
-    return;
-  }
-  unlogged_samples_->Accumulate(value, count);
-
-  FindAndRunCallback(value);
-}
-
-std::unique_ptr<HistogramSamples> Histogram::SnapshotSamples() const {
-  return SnapshotAllSamples();
-}
-
-std::unique_ptr<HistogramSamples> Histogram::SnapshotDelta() {
-#if DCHECK_IS_ON()
-  DCHECK(!final_delta_created_);
-#endif
-
-  // The code below has subtle thread-safety guarantees! All changes to
-  // the underlying SampleVectors use atomic integer operations, which guarantee
-  // eventual consistency, but do not guarantee full synchronization between
-  // different entries in the SampleVector. In particular, this means that
-  // concurrent updates to the histogram might result in the reported sum not
-  // matching the individual bucket counts; or there being some buckets that are
-  // logically updated "together", but end up being only partially updated when
-  // a snapshot is captured. Note that this is why it's important to subtract
-  // exactly the snapshotted unlogged samples, rather than simply resetting the
-  // vector: this way, the next snapshot will include any concurrent updates
-  // missed by the current snapshot.
-
-  std::unique_ptr<HistogramSamples> snapshot = SnapshotUnloggedSamples();
-  unlogged_samples_->Subtract(*snapshot);
-  logged_samples_->Add(*snapshot);
-
-  return snapshot;
-}
-
-std::unique_ptr<HistogramSamples> Histogram::SnapshotFinalDelta() const {
-#if DCHECK_IS_ON()
-  DCHECK(!final_delta_created_);
-  final_delta_created_ = true;
-#endif
-
-  return SnapshotUnloggedSamples();
-}
-
-void Histogram::AddSamples(const HistogramSamples& samples) {
-  unlogged_samples_->Add(samples);
-}
-
-bool Histogram::AddSamplesFromPickle(PickleIterator* iter) {
-  return unlogged_samples_->AddFromPickle(iter);
-}
-
-// The following methods provide a graphical histogram display.
-void Histogram::WriteHTMLGraph(std::string* output) const {
-  // TBD(jar) Write a nice HTML bar chart, with divs an mouse-overs etc.
-  output->append("<PRE>");
-  WriteAsciiImpl(true, "<br>", output);
-  output->append("</PRE>");
-}
-
-void Histogram::WriteAscii(std::string* output) const {
-  WriteAsciiImpl(true, "\n", output);
-}
-
-void Histogram::ValidateHistogramContents() const {
-  CHECK(unlogged_samples_);
-  CHECK(unlogged_samples_->bucket_ranges());
-  CHECK(logged_samples_);
-  CHECK(logged_samples_->bucket_ranges());
-#if !defined(OS_NACL)
-  if (0U == logged_samples_->id() && (flags() & kIsPersistent)) {
-    // ID should never be zero. If it is, then it's probably because the
-    // entire memory page was cleared. Check that this is true.
-    // TODO(bcwhite): Remove this.
-    // https://bugs.chromium.org/p/chromium/issues/detail?id=836875
-    size_t page_size = SysInfo::VMAllocationGranularity();
-    if (page_size == 0)
-      page_size = 1024;
-    const int* address = reinterpret_cast<const int*>(
-        reinterpret_cast<uintptr_t>(logged_samples_->meta()) &
-        ~(page_size - 1));
-    // Check a couple places so there is evidence in a crash report as to
-    // where it was non-zero.
-    CHECK_EQ(0, address[0]);
-    CHECK_EQ(0, address[1]);
-    CHECK_EQ(0, address[2]);
-    CHECK_EQ(0, address[4]);
-    CHECK_EQ(0, address[8]);
-    CHECK_EQ(0, address[16]);
-    CHECK_EQ(0, address[32]);
-    CHECK_EQ(0, address[64]);
-    CHECK_EQ(0, address[128]);
-    CHECK_EQ(0, address[256]);
-    CHECK_EQ(0, address[512]);
-    // Now check every address.
-    for (size_t i = 0; i < page_size / sizeof(int); ++i)
-      CHECK_EQ(0, address[i]);
-  }
-#endif
-  CHECK_NE(0U, logged_samples_->id());
-}
-
-void Histogram::SerializeInfoImpl(Pickle* pickle) const {
-  DCHECK(bucket_ranges()->HasValidChecksum());
-  pickle->WriteString(histogram_name());
-  pickle->WriteInt(flags());
-  pickle->WriteInt(declared_min());
-  pickle->WriteInt(declared_max());
-  pickle->WriteUInt32(bucket_count());
-  pickle->WriteUInt32(bucket_ranges()->checksum());
-}
-
-// TODO(bcwhite): Remove minimum/maximum parameters from here and call chain.
-Histogram::Histogram(const char* name,
-                     Sample minimum,
-                     Sample maximum,
-                     const BucketRanges* ranges)
-    : HistogramBase(name) {
-  DCHECK(ranges) << name << ": " << minimum << "-" << maximum;
-  unlogged_samples_.reset(new SampleVector(HashMetricName(name), ranges));
-  logged_samples_.reset(new SampleVector(unlogged_samples_->id(), ranges));
-}
-
-Histogram::Histogram(const char* name,
-                     Sample minimum,
-                     Sample maximum,
-                     const BucketRanges* ranges,
-                     const DelayedPersistentAllocation& counts,
-                     const DelayedPersistentAllocation& logged_counts,
-                     HistogramSamples::Metadata* meta,
-                     HistogramSamples::Metadata* logged_meta)
-    : HistogramBase(name) {
-  DCHECK(ranges) << name << ": " << minimum << "-" << maximum;
-  unlogged_samples_.reset(
-      new PersistentSampleVector(HashMetricName(name), ranges, meta, counts));
-  logged_samples_.reset(new PersistentSampleVector(
-      unlogged_samples_->id(), ranges, logged_meta, logged_counts));
-}
-
-Histogram::~Histogram() = default;
-
-bool Histogram::PrintEmptyBucket(uint32_t index) const {
-  return true;
-}
-
-// Use the actual bucket widths (like a linear histogram) until the widths get
-// over some transition value, and then use that transition width.  Exponentials
-// get so big so fast (and we don't expect to see a lot of entries in the large
-// buckets), so we need this to make it possible to see what is going on and
-// not have 0-graphical-height buckets.
-double Histogram::GetBucketSize(Count current, uint32_t i) const {
-  DCHECK_GT(ranges(i + 1), ranges(i));
-  static const double kTransitionWidth = 5;
-  double denominator = ranges(i + 1) - ranges(i);
-  if (denominator > kTransitionWidth)
-    denominator = kTransitionWidth;  // Stop trying to normalize.
-  return current/denominator;
-}
-
-const std::string Histogram::GetAsciiBucketRange(uint32_t i) const {
-  return GetSimpleAsciiBucketRange(ranges(i));
-}
-
-//------------------------------------------------------------------------------
-// Private methods
-
-// static
-HistogramBase* Histogram::DeserializeInfoImpl(PickleIterator* iter) {
-  std::string histogram_name;
-  int flags;
-  int declared_min;
-  int declared_max;
-  uint32_t bucket_count;
-  uint32_t range_checksum;
-
-  if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min,
-                              &declared_max, &bucket_count, &range_checksum)) {
-    return nullptr;
-  }
-
-  // Find or create the local version of the histogram in this process.
-  HistogramBase* histogram = Histogram::FactoryGet(
-      histogram_name, declared_min, declared_max, bucket_count, flags);
-  if (!histogram)
-    return nullptr;
-
-  // The serialized histogram might be corrupted.
-  if (!ValidateRangeChecksum(*histogram, range_checksum))
-    return nullptr;
-
-  return histogram;
-}
-
-std::unique_ptr<SampleVector> Histogram::SnapshotAllSamples() const {
-  std::unique_ptr<SampleVector> samples = SnapshotUnloggedSamples();
-  samples->Add(*logged_samples_);
-  return samples;
-}
-
-std::unique_ptr<SampleVector> Histogram::SnapshotUnloggedSamples() const {
-  std::unique_ptr<SampleVector> samples(
-      new SampleVector(unlogged_samples_->id(), bucket_ranges()));
-  samples->Add(*unlogged_samples_);
-  return samples;
-}
-
-void Histogram::WriteAsciiImpl(bool graph_it,
-                               const std::string& newline,
-                               std::string* output) const {
-  // Get local (stack) copies of all effectively volatile class data so that we
-  // are consistent across our output activities.
-  std::unique_ptr<SampleVector> snapshot = SnapshotAllSamples();
-  Count sample_count = snapshot->TotalCount();
-
-  WriteAsciiHeader(*snapshot, sample_count, output);
-  output->append(newline);
-
-  // Prepare to normalize graphical rendering of bucket contents.
-  double max_size = 0;
-  if (graph_it)
-    max_size = GetPeakBucketSize(*snapshot);
-
-  // Calculate space needed to print bucket range numbers.  Leave room to print
-  // nearly the largest bucket range without sliding over the histogram.
-  uint32_t largest_non_empty_bucket = bucket_count() - 1;
-  while (0 == snapshot->GetCountAtIndex(largest_non_empty_bucket)) {
-    if (0 == largest_non_empty_bucket)
-      break;  // All buckets are empty.
-    --largest_non_empty_bucket;
-  }
-
-  // Calculate largest print width needed for any of our bucket range displays.
-  size_t print_width = 1;
-  for (uint32_t i = 0; i < bucket_count(); ++i) {
-    if (snapshot->GetCountAtIndex(i)) {
-      size_t width = GetAsciiBucketRange(i).size() + 1;
-      if (width > print_width)
-        print_width = width;
-    }
-  }
-
-  int64_t remaining = sample_count;
-  int64_t past = 0;
-  // Output the actual histogram graph.
-  for (uint32_t i = 0; i < bucket_count(); ++i) {
-    Count current = snapshot->GetCountAtIndex(i);
-    if (!current && !PrintEmptyBucket(i))
-      continue;
-    remaining -= current;
-    std::string range = GetAsciiBucketRange(i);
-    output->append(range);
-    for (size_t j = 0; range.size() + j < print_width + 1; ++j)
-      output->push_back(' ');
-    if (0 == current && i < bucket_count() - 1 &&
-        0 == snapshot->GetCountAtIndex(i + 1)) {
-      while (i < bucket_count() - 1 &&
-             0 == snapshot->GetCountAtIndex(i + 1)) {
-        ++i;
-      }
-      output->append("... ");
-      output->append(newline);
-      continue;  // No reason to plot emptiness.
-    }
-    double current_size = GetBucketSize(current, i);
-    if (graph_it)
-      WriteAsciiBucketGraph(current_size, max_size, output);
-    WriteAsciiBucketContext(past, current, remaining, i, output);
-    output->append(newline);
-    past += current;
-  }
-  DCHECK_EQ(sample_count, past);
-}
-
-double Histogram::GetPeakBucketSize(const SampleVectorBase& samples) const {
-  double max = 0;
-  for (uint32_t i = 0; i < bucket_count() ; ++i) {
-    double current_size = GetBucketSize(samples.GetCountAtIndex(i), i);
-    if (current_size > max)
-      max = current_size;
-  }
-  return max;
-}
-
-void Histogram::WriteAsciiHeader(const SampleVectorBase& samples,
-                                 Count sample_count,
-                                 std::string* output) const {
-  StringAppendF(output, "Histogram: %s recorded %d samples", histogram_name(),
-                sample_count);
-  if (sample_count == 0) {
-    DCHECK_EQ(samples.sum(), 0);
-  } else {
-    double mean = static_cast<float>(samples.sum()) / sample_count;
-    StringAppendF(output, ", mean = %.1f", mean);
-  }
-  if (flags())
-    StringAppendF(output, " (flags = 0x%x)", flags());
-}
-
-void Histogram::WriteAsciiBucketContext(const int64_t past,
-                                        const Count current,
-                                        const int64_t remaining,
-                                        const uint32_t i,
-                                        std::string* output) const {
-  double scaled_sum = (past + current + remaining) / 100.0;
-  WriteAsciiBucketValue(current, scaled_sum, output);
-  if (0 < i) {
-    double percentage = past / scaled_sum;
-    StringAppendF(output, " {%3.1f%%}", percentage);
-  }
-}
-
-void Histogram::GetParameters(DictionaryValue* params) const {
-  params->SetString("type", HistogramTypeToString(GetHistogramType()));
-  params->SetInteger("min", declared_min());
-  params->SetInteger("max", declared_max());
-  params->SetInteger("bucket_count", static_cast<int>(bucket_count()));
-}
-
-void Histogram::GetCountAndBucketData(Count* count,
-                                      int64_t* sum,
-                                      ListValue* buckets) const {
-  std::unique_ptr<SampleVector> snapshot = SnapshotAllSamples();
-  *count = snapshot->TotalCount();
-  *sum = snapshot->sum();
-  uint32_t index = 0;
-  for (uint32_t i = 0; i < bucket_count(); ++i) {
-    Sample count_at_index = snapshot->GetCountAtIndex(i);
-    if (count_at_index > 0) {
-      std::unique_ptr<DictionaryValue> bucket_value(new DictionaryValue());
-      bucket_value->SetInteger("low", ranges(i));
-      if (i != bucket_count() - 1)
-        bucket_value->SetInteger("high", ranges(i + 1));
-      bucket_value->SetInteger("count", count_at_index);
-      buckets->Set(index, std::move(bucket_value));
-      ++index;
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-// LinearHistogram: This histogram uses a traditional set of evenly spaced
-// buckets.
-//------------------------------------------------------------------------------
-
-class LinearHistogram::Factory : public Histogram::Factory {
- public:
-  Factory(const std::string& name,
-          HistogramBase::Sample minimum,
-          HistogramBase::Sample maximum,
-          uint32_t bucket_count,
-          int32_t flags,
-          const DescriptionPair* descriptions)
-    : Histogram::Factory(name, LINEAR_HISTOGRAM, minimum, maximum,
-                         bucket_count, flags) {
-    descriptions_ = descriptions;
-  }
-
- protected:
-  BucketRanges* CreateRanges() override {
-    BucketRanges* ranges = new BucketRanges(bucket_count_ + 1);
-    LinearHistogram::InitializeBucketRanges(minimum_, maximum_, ranges);
-    return ranges;
-  }
-
-  std::unique_ptr<HistogramBase> HeapAlloc(
-      const BucketRanges* ranges) override {
-    return WrapUnique(new LinearHistogram(GetPermanentName(name_), minimum_,
-                                          maximum_, ranges));
-  }
-
-  void FillHistogram(HistogramBase* base_histogram) override {
-    Histogram::Factory::FillHistogram(base_histogram);
-    // Normally, |base_histogram| should have type LINEAR_HISTOGRAM or be
-    // inherited from it. However, if it's expired, it will actually be a
-    // DUMMY_HISTOGRAM. Skip filling in that case.
-    if (base_histogram->GetHistogramType() == DUMMY_HISTOGRAM)
-      return;
-    LinearHistogram* histogram = static_cast<LinearHistogram*>(base_histogram);
-    // Set range descriptions.
-    if (descriptions_) {
-      for (int i = 0; descriptions_[i].description; ++i) {
-        histogram->bucket_description_[descriptions_[i].sample] =
-            descriptions_[i].description;
-      }
-    }
-  }
-
- private:
-  const DescriptionPair* descriptions_;
-
-  DISALLOW_COPY_AND_ASSIGN(Factory);
-};
-
-LinearHistogram::~LinearHistogram() = default;
-
-HistogramBase* LinearHistogram::FactoryGet(const std::string& name,
-                                           Sample minimum,
-                                           Sample maximum,
-                                           uint32_t bucket_count,
-                                           int32_t flags) {
-  return FactoryGetWithRangeDescription(name, minimum, maximum, bucket_count,
-                                        flags, NULL);
-}
-
-HistogramBase* LinearHistogram::FactoryTimeGet(const std::string& name,
-                                               TimeDelta minimum,
-                                               TimeDelta maximum,
-                                               uint32_t bucket_count,
-                                               int32_t flags) {
-  return FactoryGet(name, static_cast<Sample>(minimum.InMilliseconds()),
-                    static_cast<Sample>(maximum.InMilliseconds()), bucket_count,
-                    flags);
-}
-
-HistogramBase* LinearHistogram::FactoryGet(const char* name,
-                                           Sample minimum,
-                                           Sample maximum,
-                                           uint32_t bucket_count,
-                                           int32_t flags) {
-  return FactoryGet(std::string(name), minimum, maximum, bucket_count, flags);
-}
-
-HistogramBase* LinearHistogram::FactoryTimeGet(const char* name,
-                                               TimeDelta minimum,
-                                               TimeDelta maximum,
-                                               uint32_t bucket_count,
-                                               int32_t flags) {
-  return FactoryTimeGet(std::string(name),  minimum, maximum, bucket_count,
-                        flags);
-}
-
-std::unique_ptr<HistogramBase> LinearHistogram::PersistentCreate(
-    const char* name,
-    Sample minimum,
-    Sample maximum,
-    const BucketRanges* ranges,
-    const DelayedPersistentAllocation& counts,
-    const DelayedPersistentAllocation& logged_counts,
-    HistogramSamples::Metadata* meta,
-    HistogramSamples::Metadata* logged_meta) {
-  return WrapUnique(new LinearHistogram(name, minimum, maximum, ranges, counts,
-                                        logged_counts, meta, logged_meta));
-}
-
-HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
-    const std::string& name,
-    Sample minimum,
-    Sample maximum,
-    uint32_t bucket_count,
-    int32_t flags,
-    const DescriptionPair descriptions[]) {
-  bool valid_arguments = Histogram::InspectConstructionArguments(
-      name, &minimum, &maximum, &bucket_count);
-  DCHECK(valid_arguments);
-
-  return Factory(name, minimum, maximum, bucket_count, flags, descriptions)
-      .Build();
-}
-
-HistogramType LinearHistogram::GetHistogramType() const {
-  return LINEAR_HISTOGRAM;
-}
-
-LinearHistogram::LinearHistogram(const char* name,
-                                 Sample minimum,
-                                 Sample maximum,
-                                 const BucketRanges* ranges)
-    : Histogram(name, minimum, maximum, ranges) {}
-
-LinearHistogram::LinearHistogram(
-    const char* name,
-    Sample minimum,
-    Sample maximum,
-    const BucketRanges* ranges,
-    const DelayedPersistentAllocation& counts,
-    const DelayedPersistentAllocation& logged_counts,
-    HistogramSamples::Metadata* meta,
-    HistogramSamples::Metadata* logged_meta)
-    : Histogram(name,
-                minimum,
-                maximum,
-                ranges,
-                counts,
-                logged_counts,
-                meta,
-                logged_meta) {}
-
-double LinearHistogram::GetBucketSize(Count current, uint32_t i) const {
-  DCHECK_GT(ranges(i + 1), ranges(i));
-  // Adjacent buckets with different widths would have "surprisingly" many (few)
-  // samples in a histogram if we didn't normalize this way.
-  double denominator = ranges(i + 1) - ranges(i);
-  return current/denominator;
-}
-
-const std::string LinearHistogram::GetAsciiBucketRange(uint32_t i) const {
-  int range = ranges(i);
-  BucketDescriptionMap::const_iterator it = bucket_description_.find(range);
-  if (it == bucket_description_.end())
-    return Histogram::GetAsciiBucketRange(i);
-  return it->second;
-}
-
-bool LinearHistogram::PrintEmptyBucket(uint32_t index) const {
-  return bucket_description_.find(ranges(index)) == bucket_description_.end();
-}
-
-// static
-void LinearHistogram::InitializeBucketRanges(Sample minimum,
-                                             Sample maximum,
-                                             BucketRanges* ranges) {
-  double min = minimum;
-  double max = maximum;
-  size_t bucket_count = ranges->bucket_count();
-  for (size_t i = 1; i < bucket_count; ++i) {
-    double linear_range =
-        (min * (bucket_count - 1 - i) + max * (i - 1)) / (bucket_count - 2);
-    ranges->set_range(i, static_cast<Sample>(linear_range + 0.5));
-  }
-  ranges->set_range(ranges->bucket_count(), HistogramBase::kSampleType_MAX);
-  ranges->ResetChecksum();
-}
-
-// static
-HistogramBase* LinearHistogram::DeserializeInfoImpl(PickleIterator* iter) {
-  std::string histogram_name;
-  int flags;
-  int declared_min;
-  int declared_max;
-  uint32_t bucket_count;
-  uint32_t range_checksum;
-
-  if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min,
-                              &declared_max, &bucket_count, &range_checksum)) {
-    return nullptr;
-  }
-
-  HistogramBase* histogram = LinearHistogram::FactoryGet(
-      histogram_name, declared_min, declared_max, bucket_count, flags);
-  if (!histogram)
-    return nullptr;
-
-  if (!ValidateRangeChecksum(*histogram, range_checksum)) {
-    // The serialized histogram might be corrupted.
-    return nullptr;
-  }
-  return histogram;
-}
-
-//------------------------------------------------------------------------------
-// This section provides implementation for BooleanHistogram.
-//------------------------------------------------------------------------------
-
-class BooleanHistogram::Factory : public Histogram::Factory {
- public:
-  Factory(const std::string& name, int32_t flags)
-    : Histogram::Factory(name, BOOLEAN_HISTOGRAM, 1, 2, 3, flags) {}
-
- protected:
-  BucketRanges* CreateRanges() override {
-    BucketRanges* ranges = new BucketRanges(3 + 1);
-    LinearHistogram::InitializeBucketRanges(1, 2, ranges);
-    return ranges;
-  }
-
-  std::unique_ptr<HistogramBase> HeapAlloc(
-      const BucketRanges* ranges) override {
-    return WrapUnique(new BooleanHistogram(GetPermanentName(name_), ranges));
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Factory);
-};
-
-HistogramBase* BooleanHistogram::FactoryGet(const std::string& name,
-                                            int32_t flags) {
-  return Factory(name, flags).Build();
-}
-
-HistogramBase* BooleanHistogram::FactoryGet(const char* name, int32_t flags) {
-  return FactoryGet(std::string(name), flags);
-}
-
-std::unique_ptr<HistogramBase> BooleanHistogram::PersistentCreate(
-    const char* 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));
-}
-
-HistogramType BooleanHistogram::GetHistogramType() const {
-  return BOOLEAN_HISTOGRAM;
-}
-
-BooleanHistogram::BooleanHistogram(const char* name, const BucketRanges* ranges)
-    : LinearHistogram(name, 1, 2, ranges) {}
-
-BooleanHistogram::BooleanHistogram(
-    const char* name,
-    const BucketRanges* ranges,
-    const DelayedPersistentAllocation& counts,
-    const DelayedPersistentAllocation& logged_counts,
-    HistogramSamples::Metadata* meta,
-    HistogramSamples::Metadata* logged_meta)
-    : LinearHistogram(name,
-                      1,
-                      2,
-                      ranges,
-                      counts,
-                      logged_counts,
-                      meta,
-                      logged_meta) {}
-
-HistogramBase* BooleanHistogram::DeserializeInfoImpl(PickleIterator* iter) {
-  std::string histogram_name;
-  int flags;
-  int declared_min;
-  int declared_max;
-  uint32_t bucket_count;
-  uint32_t range_checksum;
-
-  if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min,
-                              &declared_max, &bucket_count, &range_checksum)) {
-    return nullptr;
-  }
-
-  HistogramBase* histogram = BooleanHistogram::FactoryGet(
-      histogram_name, flags);
-  if (!histogram)
-    return nullptr;
-
-  if (!ValidateRangeChecksum(*histogram, range_checksum)) {
-    // The serialized histogram might be corrupted.
-    return nullptr;
-  }
-  return histogram;
-}
-
-//------------------------------------------------------------------------------
-// CustomHistogram:
-//------------------------------------------------------------------------------
-
-class CustomHistogram::Factory : public Histogram::Factory {
- public:
-  Factory(const std::string& name,
-          const std::vector<Sample>* custom_ranges,
-          int32_t flags)
-    : Histogram::Factory(name, CUSTOM_HISTOGRAM, 0, 0, 0, flags) {
-    custom_ranges_ = custom_ranges;
-  }
-
- protected:
-  BucketRanges* CreateRanges() override {
-    // Remove the duplicates in the custom ranges array.
-    std::vector<int> ranges = *custom_ranges_;
-    ranges.push_back(0);  // Ensure we have a zero value.
-    ranges.push_back(HistogramBase::kSampleType_MAX);
-    std::sort(ranges.begin(), ranges.end());
-    ranges.erase(std::unique(ranges.begin(), ranges.end()), ranges.end());
-
-    BucketRanges* bucket_ranges = new BucketRanges(ranges.size());
-    for (uint32_t i = 0; i < ranges.size(); i++) {
-      bucket_ranges->set_range(i, ranges[i]);
-    }
-    bucket_ranges->ResetChecksum();
-    return bucket_ranges;
-  }
-
-  std::unique_ptr<HistogramBase> HeapAlloc(
-      const BucketRanges* ranges) override {
-    return WrapUnique(new CustomHistogram(GetPermanentName(name_), ranges));
-  }
-
- private:
-  const std::vector<Sample>* custom_ranges_;
-
-  DISALLOW_COPY_AND_ASSIGN(Factory);
-};
-
-HistogramBase* CustomHistogram::FactoryGet(
-    const std::string& name,
-    const std::vector<Sample>& custom_ranges,
-    int32_t flags) {
-  CHECK(ValidateCustomRanges(custom_ranges));
-
-  return Factory(name, &custom_ranges, flags).Build();
-}
-
-HistogramBase* CustomHistogram::FactoryGet(
-    const char* name,
-    const std::vector<Sample>& custom_ranges,
-    int32_t flags) {
-  return FactoryGet(std::string(name), custom_ranges, flags);
-}
-
-std::unique_ptr<HistogramBase> CustomHistogram::PersistentCreate(
-    const char* 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));
-}
-
-HistogramType CustomHistogram::GetHistogramType() const {
-  return CUSTOM_HISTOGRAM;
-}
-
-// static
-std::vector<Sample> CustomHistogram::ArrayToCustomEnumRanges(
-    base::span<const Sample> values) {
-  std::vector<Sample> all_values;
-  for (Sample value : values) {
-    all_values.push_back(value);
-
-    // Ensure that a guard bucket is added. If we end up with duplicate
-    // values, FactoryGet will take care of removing them.
-    all_values.push_back(value + 1);
-  }
-  return all_values;
-}
-
-CustomHistogram::CustomHistogram(const char* name, const BucketRanges* ranges)
-    : Histogram(name,
-                ranges->range(1),
-                ranges->range(ranges->bucket_count() - 1),
-                ranges) {}
-
-CustomHistogram::CustomHistogram(
-    const char* name,
-    const BucketRanges* ranges,
-    const DelayedPersistentAllocation& counts,
-    const DelayedPersistentAllocation& logged_counts,
-    HistogramSamples::Metadata* meta,
-    HistogramSamples::Metadata* logged_meta)
-    : Histogram(name,
-                ranges->range(1),
-                ranges->range(ranges->bucket_count() - 1),
-                ranges,
-                counts,
-                logged_counts,
-                meta,
-                logged_meta) {}
-
-void CustomHistogram::SerializeInfoImpl(Pickle* pickle) const {
-  Histogram::SerializeInfoImpl(pickle);
-
-  // Serialize ranges. First and last ranges are alwasy 0 and INT_MAX, so don't
-  // write them.
-  for (uint32_t i = 1; i < bucket_ranges()->bucket_count(); ++i)
-    pickle->WriteInt(bucket_ranges()->range(i));
-}
-
-double CustomHistogram::GetBucketSize(Count current, uint32_t i) const {
-  // If this is a histogram of enum values, normalizing the bucket count
-  // by the bucket range is not helpful, so just return the bucket count.
-  return current;
-}
-
-// static
-HistogramBase* CustomHistogram::DeserializeInfoImpl(PickleIterator* iter) {
-  std::string histogram_name;
-  int flags;
-  int declared_min;
-  int declared_max;
-  uint32_t bucket_count;
-  uint32_t range_checksum;
-
-  if (!ReadHistogramArguments(iter, &histogram_name, &flags, &declared_min,
-                              &declared_max, &bucket_count, &range_checksum)) {
-    return nullptr;
-  }
-
-  // First and last ranges are not serialized.
-  std::vector<Sample> sample_ranges(bucket_count - 1);
-
-  for (uint32_t i = 0; i < sample_ranges.size(); ++i) {
-    if (!iter->ReadInt(&sample_ranges[i]))
-      return nullptr;
-  }
-
-  HistogramBase* histogram = CustomHistogram::FactoryGet(
-      histogram_name, sample_ranges, flags);
-  if (!histogram)
-    return nullptr;
-
-  if (!ValidateRangeChecksum(*histogram, range_checksum)) {
-    // The serialized histogram might be corrupted.
-    return nullptr;
-  }
-  return histogram;
-}
-
-// static
-bool CustomHistogram::ValidateCustomRanges(
-    const std::vector<Sample>& custom_ranges) {
-  bool has_valid_range = false;
-  for (uint32_t i = 0; i < custom_ranges.size(); i++) {
-    Sample sample = custom_ranges[i];
-    if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1)
-      return false;
-    if (sample != 0)
-      has_valid_range = true;
-  }
-  return has_valid_range;
-}
-
-}  // namespace base
diff --git a/base/metrics/histogram.h b/base/metrics/histogram.h
deleted file mode 100644
index 35d8370..0000000
--- a/base/metrics/histogram.h
+++ /dev/null
@@ -1,559 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Histogram is an object that aggregates statistics, and can summarize them in
-// various forms, including ASCII graphical, HTML, and numerically (as a
-// vector of numbers corresponding to each of the aggregating buckets).
-
-// It supports calls to accumulate either time intervals (which are processed
-// as integral number of milliseconds), or arbitrary integral units.
-
-// For Histogram (exponential histogram), LinearHistogram and CustomHistogram,
-// the minimum for a declared range is 1 (instead of 0), while the maximum is
-// (HistogramBase::kSampleType_MAX - 1). However, there will always be underflow
-// and overflow buckets added automatically, so a 0 bucket will always exist
-// even when a minimum value of 1 is specified.
-
-// Each use of a histogram with the same name will reference the same underlying
-// data, so it is safe to record to the same histogram from multiple locations
-// in the code. It is a runtime error if all uses of the same histogram do not
-// agree exactly in type, bucket size and range.
-
-// For Histogram and LinearHistogram, the maximum for a declared range should
-// always be larger (not equal) than minimal range. Zero and
-// HistogramBase::kSampleType_MAX are implicitly added as first and last ranges,
-// so the smallest legal bucket_count is 3. However CustomHistogram can have
-// bucket count as 2 (when you give a custom ranges vector containing only 1
-// range).
-// For these 3 kinds of histograms, the max bucket count is always
-// (Histogram::kBucketCount_MAX - 1).
-
-// The buckets layout of class Histogram is exponential. For example, buckets
-// might contain (sequentially) the count of values in the following intervals:
-// [0,1), [1,2), [2,4), [4,8), [8,16), [16,32), [32,64), [64,infinity)
-// That bucket allocation would actually result from construction of a histogram
-// for values between 1 and 64, with 8 buckets, such as:
-// Histogram count("some name", 1, 64, 8);
-// Note that the underflow bucket [0,1) and the overflow bucket [64,infinity)
-// are also counted by the constructor in the user supplied "bucket_count"
-// argument.
-// The above example has an exponential ratio of 2 (doubling the bucket width
-// in each consecutive bucket).  The Histogram class automatically calculates
-// the smallest ratio that it can use to construct the number of buckets
-// selected in the constructor.  An another example, if you had 50 buckets,
-// and millisecond time values from 1 to 10000, then the ratio between
-// consecutive bucket widths will be approximately somewhere around the 50th
-// root of 10000.  This approach provides very fine grain (narrow) buckets
-// at the low end of the histogram scale, but allows the histogram to cover a
-// gigantic range with the addition of very few buckets.
-
-// Usually we use macros to define and use a histogram, which are defined in
-// base/metrics/histogram_macros.h. Note: Callers should include that header
-// directly if they only access the histogram APIs through macros.
-//
-// Macros use a pattern involving a function static variable, that is a pointer
-// to a histogram.  This static is explicitly initialized on any thread
-// that detects a uninitialized (NULL) pointer.  The potentially racy
-// initialization is not a problem as it is always set to point to the same
-// value (i.e., the FactoryGet always returns the same value).  FactoryGet
-// is also completely thread safe, which results in a completely thread safe,
-// and relatively fast, set of counters.  To avoid races at shutdown, the static
-// pointer is NOT deleted, and we leak the histograms at process termination.
-
-#ifndef BASE_METRICS_HISTOGRAM_H_
-#define BASE_METRICS_HISTOGRAM_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/compiler_specific.h"
-#include "base/containers/span.h"
-#include "base/gtest_prod_util.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/metrics/bucket_ranges.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/strings/string_piece.h"
-#include "base/time/time.h"
-
-namespace base {
-
-class BooleanHistogram;
-class CustomHistogram;
-class DelayedPersistentAllocation;
-class Histogram;
-class LinearHistogram;
-class Pickle;
-class PickleIterator;
-class SampleVector;
-class SampleVectorBase;
-
-class BASE_EXPORT Histogram : public HistogramBase {
- public:
-  // Initialize maximum number of buckets in histograms as 16,384.
-  static const uint32_t kBucketCount_MAX;
-
-  typedef std::vector<Count> Counts;
-
-  ~Histogram() override;
-
-  //----------------------------------------------------------------------------
-  // For a valid histogram, input should follow these restrictions:
-  // minimum > 0 (if a minimum below 1 is specified, it will implicitly be
-  //              normalized up to 1)
-  // maximum > minimum
-  // buckets > 2 [minimum buckets needed: underflow, overflow and the range]
-  // Additionally,
-  // buckets <= (maximum - minimum + 2) - this is to ensure that we don't have
-  // more buckets than the range of numbers; having more buckets than 1 per
-  // value in the range would be nonsensical.
-  static HistogramBase* FactoryGet(const std::string& name,
-                                   Sample minimum,
-                                   Sample maximum,
-                                   uint32_t bucket_count,
-                                   int32_t flags);
-  static HistogramBase* FactoryTimeGet(const std::string& name,
-                                       base::TimeDelta minimum,
-                                       base::TimeDelta maximum,
-                                       uint32_t bucket_count,
-                                       int32_t flags);
-  static HistogramBase* FactoryMicrosecondsTimeGet(const std::string& name,
-                                                   base::TimeDelta minimum,
-                                                   base::TimeDelta maximum,
-                                                   uint32_t bucket_count,
-                                                   int32_t flags);
-
-  // Overloads of the above functions that take a const char* |name| param, to
-  // avoid code bloat from the std::string constructor being inlined into call
-  // sites.
-  static HistogramBase* FactoryGet(const char* name,
-                                   Sample minimum,
-                                   Sample maximum,
-                                   uint32_t bucket_count,
-                                   int32_t flags);
-  static HistogramBase* FactoryTimeGet(const char* name,
-                                       base::TimeDelta minimum,
-                                       base::TimeDelta maximum,
-                                       uint32_t bucket_count,
-                                       int32_t flags);
-  static HistogramBase* FactoryMicrosecondsTimeGet(const char* name,
-                                                   base::TimeDelta minimum,
-                                                   base::TimeDelta maximum,
-                                                   uint32_t bucket_count,
-                                                   int32_t flags);
-
-  // Create a histogram using data in persistent storage.
-  static std::unique_ptr<HistogramBase> PersistentCreate(
-      const char* name,
-      Sample minimum,
-      Sample maximum,
-      const BucketRanges* ranges,
-      const DelayedPersistentAllocation& counts,
-      const DelayedPersistentAllocation& logged_counts,
-      HistogramSamples::Metadata* meta,
-      HistogramSamples::Metadata* logged_meta);
-
-  static void InitializeBucketRanges(Sample minimum,
-                                     Sample maximum,
-                                     BucketRanges* ranges);
-
-  // This constant if for FindCorruption. Since snapshots of histograms are
-  // taken asynchronously relative to sampling, and our counting code currently
-  // does not prevent race conditions, it is pretty likely that we'll catch a
-  // redundant count that doesn't match the sample count.  We allow for a
-  // certain amount of slop before flagging this as an inconsistency. Even with
-  // an inconsistency, we'll snapshot it again (for UMA in about a half hour),
-  // so we'll eventually get the data, if it was not the result of a corruption.
-  static const int kCommonRaceBasedCountMismatch;
-
-  // Check to see if bucket ranges, counts and tallies in the snapshot are
-  // consistent with the bucket ranges and checksums in our histogram.  This can
-  // produce a false-alarm if a race occurred in the reading of the data during
-  // a SnapShot process, but should otherwise be false at all times (unless we
-  // have memory over-writes, or DRAM failures). Flag definitions are located
-  // under "enum Inconsistency" in base/metrics/histogram_base.h.
-  uint32_t FindCorruption(const HistogramSamples& samples) const override;
-
-  //----------------------------------------------------------------------------
-  // Accessors for factory construction, serialization and testing.
-  //----------------------------------------------------------------------------
-  const BucketRanges* bucket_ranges() const;
-  Sample declared_min() const;
-  Sample declared_max() const;
-  virtual Sample ranges(uint32_t i) const;
-  virtual uint32_t bucket_count() const;
-
-  // This function validates histogram construction arguments. It returns false
-  // if some of the arguments are bad but also corrects them so they should
-  // function on non-dcheck builds without crashing.
-  // Note. Currently it allow some bad input, e.g. 0 as minimum, but silently
-  // converts it to good input: 1.
-  // TODO(bcwhite): Use false returns to create "sink" histograms so that bad
-  // data doesn't create confusion on the servers.
-  static bool InspectConstructionArguments(StringPiece name,
-                                           Sample* minimum,
-                                           Sample* maximum,
-                                           uint32_t* bucket_count);
-
-  // HistogramBase implementation:
-  uint64_t name_hash() const override;
-  HistogramType GetHistogramType() const override;
-  bool HasConstructionArguments(Sample expected_minimum,
-                                Sample expected_maximum,
-                                uint32_t expected_bucket_count) const override;
-  void Add(Sample value) override;
-  void AddCount(Sample value, int count) override;
-  std::unique_ptr<HistogramSamples> SnapshotSamples() const override;
-  std::unique_ptr<HistogramSamples> SnapshotDelta() override;
-  std::unique_ptr<HistogramSamples> SnapshotFinalDelta() const override;
-  void AddSamples(const HistogramSamples& samples) override;
-  bool AddSamplesFromPickle(base::PickleIterator* iter) override;
-  void WriteHTMLGraph(std::string* output) const override;
-  void WriteAscii(std::string* output) const override;
-
-  // Validates the histogram contents and CHECKs on errors.
-  // TODO(bcwhite): Remove this after https://crbug/836875.
-  void ValidateHistogramContents() const override;
-
- protected:
-  // This class, defined entirely within the .cc file, contains all the
-  // common logic for building a Histogram and can be overridden by more
-  // specific types to alter details of how the creation is done. It is
-  // defined as an embedded class (rather than an anonymous one) so it
-  // can access the protected constructors.
-  class Factory;
-
-  // |ranges| should contain the underflow and overflow buckets. See top
-  // comments for example.
-  Histogram(const char* name,
-            Sample minimum,
-            Sample maximum,
-            const BucketRanges* ranges);
-
-  // Traditionally, histograms allocate their own memory for the bucket
-  // vector but "shared" histograms use memory regions allocated from a
-  // special memory segment that is passed in here.  It is assumed that
-  // 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,
-            Sample minimum,
-            Sample maximum,
-            const BucketRanges* ranges,
-            const DelayedPersistentAllocation& counts,
-            const DelayedPersistentAllocation& logged_counts,
-            HistogramSamples::Metadata* meta,
-            HistogramSamples::Metadata* logged_meta);
-
-  // HistogramBase implementation:
-  void SerializeInfoImpl(base::Pickle* pickle) const override;
-
-  // Method to override to skip the display of the i'th bucket if it's empty.
-  virtual bool PrintEmptyBucket(uint32_t index) const;
-
-  // Get normalized size, relative to the ranges(i).
-  virtual double GetBucketSize(Count current, uint32_t i) const;
-
-  // Return a string description of what goes in a given bucket.
-  // Most commonly this is the numeric value, but in derived classes it may
-  // be a name (or string description) given to the bucket.
-  virtual const std::string GetAsciiBucketRange(uint32_t it) const;
-
- private:
-  // Allow tests to corrupt our innards for testing purposes.
-  FRIEND_TEST_ALL_PREFIXES(HistogramTest, BoundsTest);
-  FRIEND_TEST_ALL_PREFIXES(HistogramTest, BucketPlacementTest);
-  FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts);
-
-  friend class StatisticsRecorder;  // To allow it to delete duplicates.
-  friend class StatisticsRecorderTest;
-
-  friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo(
-      base::PickleIterator* iter);
-  static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter);
-
-  // Create a snapshot containing all samples (both logged and unlogged).
-  // Implementation of SnapshotSamples method with a more specific type for
-  // internal use.
-  std::unique_ptr<SampleVector> SnapshotAllSamples() const;
-
-  // Create a copy of unlogged samples.
-  std::unique_ptr<SampleVector> SnapshotUnloggedSamples() const;
-
-  //----------------------------------------------------------------------------
-  // Helpers for emitting Ascii graphic.  Each method appends data to output.
-
-  void WriteAsciiImpl(bool graph_it,
-                      const std::string& newline,
-                      std::string* output) const;
-
-  // Find out how large (graphically) the largest bucket will appear to be.
-  double GetPeakBucketSize(const SampleVectorBase& samples) const;
-
-  // Write a common header message describing this histogram.
-  void WriteAsciiHeader(const SampleVectorBase& samples,
-                        Count sample_count,
-                        std::string* output) const;
-
-  // Write information about previous, current, and next buckets.
-  // Information such as cumulative percentage, etc.
-  void WriteAsciiBucketContext(const int64_t past,
-                               const Count current,
-                               const int64_t remaining,
-                               const uint32_t i,
-                               std::string* output) const;
-
-  // WriteJSON calls these.
-  void GetParameters(DictionaryValue* params) const override;
-
-  void GetCountAndBucketData(Count* count,
-                             int64_t* sum,
-                             ListValue* buckets) const override;
-
-  // Samples that have not yet been logged with SnapshotDelta().
-  std::unique_ptr<SampleVectorBase> unlogged_samples_;
-
-  // Accumulation of all samples that have been logged with SnapshotDelta().
-  std::unique_ptr<SampleVectorBase> logged_samples_;
-
-#if DCHECK_IS_ON()  // Don't waste memory if it won't be used.
-  // Flag to indicate if PrepareFinalDelta has been previously called. It is
-  // used to DCHECK that a final delta is not created multiple times.
-  mutable bool final_delta_created_ = false;
-#endif
-
-  DISALLOW_COPY_AND_ASSIGN(Histogram);
-};
-
-//------------------------------------------------------------------------------
-
-// LinearHistogram is a more traditional histogram, with evenly spaced
-// buckets.
-class BASE_EXPORT LinearHistogram : public Histogram {
- public:
-  ~LinearHistogram() override;
-
-  /* minimum should start from 1. 0 is as minimum is invalid. 0 is an implicit
-     default underflow bucket. */
-  static HistogramBase* FactoryGet(const std::string& name,
-                                   Sample minimum,
-                                   Sample maximum,
-                                   uint32_t bucket_count,
-                                   int32_t flags);
-  static HistogramBase* FactoryTimeGet(const std::string& name,
-                                       TimeDelta minimum,
-                                       TimeDelta maximum,
-                                       uint32_t bucket_count,
-                                       int32_t flags);
-
-  // Overloads of the above two functions that take a const char* |name| param,
-  // to avoid code bloat from the std::string constructor being inlined into
-  // call sites.
-  static HistogramBase* FactoryGet(const char* name,
-                                   Sample minimum,
-                                   Sample maximum,
-                                   uint32_t bucket_count,
-                                   int32_t flags);
-  static HistogramBase* FactoryTimeGet(const char* name,
-                                       TimeDelta minimum,
-                                       TimeDelta maximum,
-                                       uint32_t bucket_count,
-                                       int32_t flags);
-
-  // Create a histogram using data in persistent storage.
-  static std::unique_ptr<HistogramBase> PersistentCreate(
-      const char* name,
-      Sample minimum,
-      Sample maximum,
-      const BucketRanges* ranges,
-      const DelayedPersistentAllocation& counts,
-      const DelayedPersistentAllocation& logged_counts,
-      HistogramSamples::Metadata* meta,
-      HistogramSamples::Metadata* logged_meta);
-
-  struct DescriptionPair {
-    Sample sample;
-    const char* description;  // Null means end of a list of pairs.
-  };
-
-  // Create a LinearHistogram and store a list of number/text values for use in
-  // writing the histogram graph.
-  // |descriptions| can be NULL, which means no special descriptions to set. If
-  // it's not NULL, the last element in the array must has a NULL in its
-  // "description" field.
-  static HistogramBase* FactoryGetWithRangeDescription(
-      const std::string& name,
-      Sample minimum,
-      Sample maximum,
-      uint32_t bucket_count,
-      int32_t flags,
-      const DescriptionPair descriptions[]);
-
-  static void InitializeBucketRanges(Sample minimum,
-                                     Sample maximum,
-                                     BucketRanges* ranges);
-
-  // Overridden from Histogram:
-  HistogramType GetHistogramType() const override;
-
- protected:
-  class Factory;
-
-  LinearHistogram(const char* name,
-                  Sample minimum,
-                  Sample maximum,
-                  const BucketRanges* ranges);
-
-  LinearHistogram(const char* name,
-                  Sample minimum,
-                  Sample maximum,
-                  const BucketRanges* ranges,
-                  const DelayedPersistentAllocation& counts,
-                  const DelayedPersistentAllocation& logged_counts,
-                  HistogramSamples::Metadata* meta,
-                  HistogramSamples::Metadata* logged_meta);
-
-  double GetBucketSize(Count current, uint32_t i) const override;
-
-  // If we have a description for a bucket, then return that.  Otherwise
-  // let parent class provide a (numeric) description.
-  const std::string GetAsciiBucketRange(uint32_t i) const override;
-
-  // Skip printing of name for numeric range if we have a name (and if this is
-  // an empty bucket).
-  bool PrintEmptyBucket(uint32_t index) const override;
-
- private:
-  friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo(
-      base::PickleIterator* iter);
-  static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter);
-
-  // For some ranges, we store a printable description of a bucket range.
-  // If there is no description, then GetAsciiBucketRange() uses parent class
-  // to provide a description.
-  typedef std::map<Sample, std::string> BucketDescriptionMap;
-  BucketDescriptionMap bucket_description_;
-
-  DISALLOW_COPY_AND_ASSIGN(LinearHistogram);
-};
-
-//------------------------------------------------------------------------------
-
-// BooleanHistogram is a histogram for booleans.
-class BASE_EXPORT BooleanHistogram : public LinearHistogram {
- public:
-  static HistogramBase* FactoryGet(const std::string& name, int32_t flags);
-
-  // Overload of the above function that takes a const char* |name| param,
-  // to avoid code bloat from the std::string constructor being inlined into
-  // call sites.
-  static HistogramBase* FactoryGet(const char* name, int32_t flags);
-
-  // Create a histogram using data in persistent storage.
-  static std::unique_ptr<HistogramBase> PersistentCreate(
-      const char* name,
-      const BucketRanges* ranges,
-      const DelayedPersistentAllocation& counts,
-      const DelayedPersistentAllocation& logged_counts,
-      HistogramSamples::Metadata* meta,
-      HistogramSamples::Metadata* logged_meta);
-
-  HistogramType GetHistogramType() const override;
-
- protected:
-  class Factory;
-
- private:
-  BooleanHistogram(const char* name, const BucketRanges* ranges);
-  BooleanHistogram(const char* name,
-                   const BucketRanges* ranges,
-                   const DelayedPersistentAllocation& counts,
-                   const DelayedPersistentAllocation& logged_counts,
-                   HistogramSamples::Metadata* meta,
-                   HistogramSamples::Metadata* logged_meta);
-
-  friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo(
-      base::PickleIterator* iter);
-  static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter);
-
-  DISALLOW_COPY_AND_ASSIGN(BooleanHistogram);
-};
-
-//------------------------------------------------------------------------------
-
-// CustomHistogram is a histogram for a set of custom integers.
-class BASE_EXPORT CustomHistogram : public Histogram {
- public:
-  // |custom_ranges| contains a vector of limits on ranges. Each limit should be
-  // > 0 and < kSampleType_MAX. (Currently 0 is still accepted for backward
-  // compatibility). The limits can be unordered or contain duplication, but
-  // client should not depend on this.
-  static HistogramBase* FactoryGet(const std::string& name,
-                                   const std::vector<Sample>& custom_ranges,
-                                   int32_t flags);
-
-  // Overload of the above function that takes a const char* |name| param,
-  // to avoid code bloat from the std::string constructor being inlined into
-  // call sites.
-  static HistogramBase* FactoryGet(const char* name,
-                                   const std::vector<Sample>& custom_ranges,
-                                   int32_t flags);
-
-  // Create a histogram using data in persistent storage.
-  static std::unique_ptr<HistogramBase> PersistentCreate(
-      const char* name,
-      const BucketRanges* ranges,
-      const DelayedPersistentAllocation& counts,
-      const DelayedPersistentAllocation& logged_counts,
-      HistogramSamples::Metadata* meta,
-      HistogramSamples::Metadata* logged_meta);
-
-  // Overridden from Histogram:
-  HistogramType GetHistogramType() const override;
-
-  // Helper method for transforming an array of valid enumeration values
-  // to the std::vector<int> expected by UMA_HISTOGRAM_CUSTOM_ENUMERATION.
-  // This function ensures that a guard bucket exists right after any
-  // valid sample value (unless the next higher sample is also a valid value),
-  // so that invalid samples never fall into the same bucket as valid samples.
-  static std::vector<Sample> ArrayToCustomEnumRanges(
-      base::span<const Sample> values);
-
- protected:
-  class Factory;
-
-  CustomHistogram(const char* name, const BucketRanges* ranges);
-
-  CustomHistogram(const char* name,
-                  const BucketRanges* ranges,
-                  const DelayedPersistentAllocation& counts,
-                  const DelayedPersistentAllocation& logged_counts,
-                  HistogramSamples::Metadata* meta,
-                  HistogramSamples::Metadata* logged_meta);
-
-  // HistogramBase implementation:
-  void SerializeInfoImpl(base::Pickle* pickle) const override;
-
-  double GetBucketSize(Count current, uint32_t i) const override;
-
- private:
-  friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo(
-      base::PickleIterator* iter);
-  static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter);
-
-  static bool ValidateCustomRanges(const std::vector<Sample>& custom_ranges);
-
-  DISALLOW_COPY_AND_ASSIGN(CustomHistogram);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_HISTOGRAM_H_
diff --git a/base/metrics/histogram_base.cc b/base/metrics/histogram_base.cc
deleted file mode 100644
index da3ae93..0000000
--- a/base/metrics/histogram_base.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/histogram_base.h"
-
-#include <limits.h>
-
-#include <memory>
-#include <set>
-#include <utility>
-
-#include "base/json/json_string_value_serializer.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/pickle.h"
-#include "base/process/process_handle.h"
-#include "base/rand_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/lock.h"
-#include "base/values.h"
-
-namespace base {
-
-std::string HistogramTypeToString(HistogramType type) {
-  switch (type) {
-    case HISTOGRAM:
-      return "HISTOGRAM";
-    case LINEAR_HISTOGRAM:
-      return "LINEAR_HISTOGRAM";
-    case BOOLEAN_HISTOGRAM:
-      return "BOOLEAN_HISTOGRAM";
-    case CUSTOM_HISTOGRAM:
-      return "CUSTOM_HISTOGRAM";
-    case SPARSE_HISTOGRAM:
-      return "SPARSE_HISTOGRAM";
-    case DUMMY_HISTOGRAM:
-      return "DUMMY_HISTOGRAM";
-  }
-  NOTREACHED();
-  return "UNKNOWN";
-}
-
-HistogramBase* DeserializeHistogramInfo(PickleIterator* iter) {
-  int type;
-  if (!iter->ReadInt(&type))
-    return nullptr;
-
-  switch (type) {
-    case HISTOGRAM:
-      return Histogram::DeserializeInfoImpl(iter);
-    case LINEAR_HISTOGRAM:
-      return LinearHistogram::DeserializeInfoImpl(iter);
-    case BOOLEAN_HISTOGRAM:
-      return BooleanHistogram::DeserializeInfoImpl(iter);
-    case CUSTOM_HISTOGRAM:
-      return CustomHistogram::DeserializeInfoImpl(iter);
-    case SPARSE_HISTOGRAM:
-      return SparseHistogram::DeserializeInfoImpl(iter);
-    default:
-      return nullptr;
-  }
-}
-
-const HistogramBase::Sample HistogramBase::kSampleType_MAX = INT_MAX;
-
-HistogramBase::HistogramBase(const char* name)
-    : histogram_name_(name), flags_(kNoFlags) {}
-
-HistogramBase::~HistogramBase() = default;
-
-void HistogramBase::CheckName(const StringPiece& name) const {
-  DCHECK_EQ(StringPiece(histogram_name()), name);
-}
-
-void HistogramBase::SetFlags(int32_t flags) {
-  HistogramBase::Count old_flags = subtle::NoBarrier_Load(&flags_);
-  subtle::NoBarrier_Store(&flags_, old_flags | flags);
-}
-
-void HistogramBase::ClearFlags(int32_t flags) {
-  HistogramBase::Count old_flags = subtle::NoBarrier_Load(&flags_);
-  subtle::NoBarrier_Store(&flags_, old_flags & ~flags);
-}
-
-void HistogramBase::AddScaled(Sample value, int count, int scale) {
-  DCHECK_LT(0, scale);
-
-  // Convert raw count and probabilistically round up/down if the remainder
-  // is more than a random number [0, scale). This gives a more accurate
-  // count when there are a large number of records. RandInt is "inclusive",
-  // hence the -1 for the max value.
-  int64_t count_scaled = count / scale;
-  if (count - (count_scaled * scale) > base::RandInt(0, scale - 1))
-    count_scaled += 1;
-  if (count_scaled == 0)
-    return;
-
-  AddCount(value, count_scaled);
-}
-
-void HistogramBase::AddKilo(Sample value, int count) {
-  AddScaled(value, count, 1000);
-}
-
-void HistogramBase::AddKiB(Sample value, int count) {
-  AddScaled(value, count, 1024);
-}
-
-void HistogramBase::AddTimeMillisecondsGranularity(const TimeDelta& time) {
-  Add(static_cast<Sample>(time.InMilliseconds()));
-}
-
-void HistogramBase::AddTimeMicrosecondsGranularity(const TimeDelta& time) {
-  // Intentionally drop high-resolution reports on clients with low-resolution
-  // clocks. High-resolution metrics cannot make use of low-resolution data and
-  // reporting it merely adds noise to the metric. https://crbug.com/807615#c16
-  if (TimeTicks::IsHighResolution())
-    Add(static_cast<Sample>(time.InMicroseconds()));
-}
-
-void HistogramBase::AddBoolean(bool value) {
-  Add(value ? 1 : 0);
-}
-
-void HistogramBase::SerializeInfo(Pickle* pickle) const {
-  pickle->WriteInt(GetHistogramType());
-  SerializeInfoImpl(pickle);
-}
-
-uint32_t HistogramBase::FindCorruption(const HistogramSamples& samples) const {
-  // Not supported by default.
-  return NO_INCONSISTENCIES;
-}
-
-void HistogramBase::ValidateHistogramContents() const {}
-
-void HistogramBase::WriteJSON(std::string* output,
-                              JSONVerbosityLevel verbosity_level) const {
-  Count count;
-  int64_t sum;
-  std::unique_ptr<ListValue> buckets(new ListValue());
-  GetCountAndBucketData(&count, &sum, buckets.get());
-  std::unique_ptr<DictionaryValue> parameters(new DictionaryValue());
-  GetParameters(parameters.get());
-
-  JSONStringValueSerializer serializer(output);
-  DictionaryValue root;
-  root.SetString("name", histogram_name());
-  root.SetInteger("count", count);
-  root.SetDouble("sum", static_cast<double>(sum));
-  root.SetInteger("flags", flags());
-  root.Set("params", std::move(parameters));
-  if (verbosity_level != JSON_VERBOSITY_LEVEL_OMIT_BUCKETS)
-    root.Set("buckets", std::move(buckets));
-  root.SetInteger("pid", GetUniqueIdForProcess());
-  serializer.Serialize(root);
-}
-
-void HistogramBase::FindAndRunCallback(HistogramBase::Sample sample) const {
-  if ((flags() & kCallbackExists) == 0)
-    return;
-
-  StatisticsRecorder::OnSampleCallback cb =
-      StatisticsRecorder::FindCallback(histogram_name());
-  if (!cb.is_null())
-    cb.Run(sample);
-}
-
-void HistogramBase::WriteAsciiBucketGraph(double current_size,
-                                          double max_size,
-                                          std::string* output) const {
-  const int k_line_length = 72;  // Maximal horizontal width of graph.
-  int x_count = static_cast<int>(k_line_length * (current_size / max_size)
-                                 + 0.5);
-  int x_remainder = k_line_length - x_count;
-
-  while (0 < x_count--)
-    output->append("-");
-  output->append("O");
-  while (0 < x_remainder--)
-    output->append(" ");
-}
-
-const std::string HistogramBase::GetSimpleAsciiBucketRange(
-    Sample sample) const {
-  return StringPrintf("%d", sample);
-}
-
-void HistogramBase::WriteAsciiBucketValue(Count current,
-                                          double scaled_sum,
-                                          std::string* output) const {
-  StringAppendF(output, " (%d = %3.1f%%)", current, current/scaled_sum);
-}
-
-// static
-char const* HistogramBase::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 LazyInstance<std::set<std::string>>::Leaky permanent_names;
-  static LazyInstance<Lock>::Leaky permanent_names_lock;
-
-  AutoLock lock(permanent_names_lock.Get());
-  auto result = permanent_names.Get().insert(name);
-  return result.first->c_str();
-}
-
-}  // namespace base
diff --git a/base/metrics/histogram_base.h b/base/metrics/histogram_base.h
deleted file mode 100644
index 010dc55..0000000
--- a/base/metrics/histogram_base.h
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_BASE_H_
-#define BASE_METRICS_HISTOGRAM_BASE_H_
-
-#include <limits.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/atomicops.h"
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/strings/string_piece.h"
-#include "base/time/time.h"
-
-namespace base {
-
-class DictionaryValue;
-class HistogramBase;
-class HistogramSamples;
-class ListValue;
-class Pickle;
-class PickleIterator;
-
-////////////////////////////////////////////////////////////////////////////////
-// This enum is used to facilitate deserialization of histograms from other
-// processes into the browser. If you create another class that inherits from
-// HistogramBase, add new histogram types and names below.
-
-enum HistogramType {
-  HISTOGRAM,
-  LINEAR_HISTOGRAM,
-  BOOLEAN_HISTOGRAM,
-  CUSTOM_HISTOGRAM,
-  SPARSE_HISTOGRAM,
-  DUMMY_HISTOGRAM,
-};
-
-// Controls the verbosity of the information when the histogram is serialized to
-// a JSON.
-// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.base.metrics
-enum JSONVerbosityLevel {
-  // The histogram is completely serialized.
-  JSON_VERBOSITY_LEVEL_FULL,
-  // The bucket information is not serialized.
-  JSON_VERBOSITY_LEVEL_OMIT_BUCKETS,
-};
-
-std::string HistogramTypeToString(HistogramType type);
-
-// This enum is used for reporting how many histograms and of what types and
-// variations are being created. It has to be in the main .h file so it is
-// visible to files that define the various histogram types.
-enum HistogramReport {
-  // Count the number of reports created. The other counts divided by this
-  // number will give the average per run of the program.
-  HISTOGRAM_REPORT_CREATED = 0,
-
-  // Count the total number of histograms created. It is the limit against
-  // which all others are compared.
-  HISTOGRAM_REPORT_HISTOGRAM_CREATED = 1,
-
-  // Count the total number of histograms looked-up. It's better to cache
-  // the result of a single lookup rather than do it repeatedly.
-  HISTOGRAM_REPORT_HISTOGRAM_LOOKUP = 2,
-
-  // These count the individual histogram types. This must follow the order
-  // of HistogramType above.
-  HISTOGRAM_REPORT_TYPE_LOGARITHMIC = 3,
-  HISTOGRAM_REPORT_TYPE_LINEAR = 4,
-  HISTOGRAM_REPORT_TYPE_BOOLEAN = 5,
-  HISTOGRAM_REPORT_TYPE_CUSTOM = 6,
-  HISTOGRAM_REPORT_TYPE_SPARSE = 7,
-
-  // These indicate the individual flags that were set.
-  HISTOGRAM_REPORT_FLAG_UMA_TARGETED = 8,
-  HISTOGRAM_REPORT_FLAG_UMA_STABILITY = 9,
-  HISTOGRAM_REPORT_FLAG_PERSISTENT = 10,
-
-  // This must be last.
-  HISTOGRAM_REPORT_MAX = 11
-};
-
-// Create or find existing histogram that matches the pickled info.
-// Returns NULL if the pickled data has problems.
-BASE_EXPORT HistogramBase* DeserializeHistogramInfo(base::PickleIterator* iter);
-
-////////////////////////////////////////////////////////////////////////////////
-
-class BASE_EXPORT HistogramBase {
- public:
-  typedef int32_t Sample;                // Used for samples.
-  typedef subtle::Atomic32 AtomicCount;  // Used to count samples.
-  typedef int32_t Count;  // Used to manipulate counts in temporaries.
-
-  static const Sample kSampleType_MAX;  // INT_MAX
-
-  enum Flags {
-    kNoFlags = 0x0,
-
-    // Histogram should be UMA uploaded.
-    kUmaTargetedHistogramFlag = 0x1,
-
-    // Indicates that this is a stability histogram. This flag exists to specify
-    // which histograms should be included in the initial stability log. Please
-    // refer to |MetricsService::PrepareInitialStabilityLog|.
-    kUmaStabilityHistogramFlag = kUmaTargetedHistogramFlag | 0x2,
-
-    // Indicates 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,
-
-    // Indicates that a callback exists for when a new sample is recorded on
-    // this histogram. We store this as a flag with the histogram since
-    // histograms can be in performance critical code, and this allows us
-    // to shortcut looking up the callback if it doesn't exist.
-    kCallbackExists = 0x20,
-
-    // Indicates that the histogram is held in "persistent" memory and may
-    // be accessible between processes. This is only possible if such a
-    // memory segment has been created/attached, used to create a Persistent-
-    // MemoryAllocator, and that loaded into the Histogram module before this
-    // histogram is created.
-    kIsPersistent = 0x40,
-  };
-
-  // Histogram data inconsistency types.
-  enum Inconsistency : uint32_t {
-    NO_INCONSISTENCIES = 0x0,
-    RANGE_CHECKSUM_ERROR = 0x1,
-    BUCKET_ORDER_ERROR = 0x2,
-    COUNT_HIGH_ERROR = 0x4,
-    COUNT_LOW_ERROR = 0x8,
-
-    NEVER_EXCEEDED_VALUE = 0x10,
-  };
-
-  // 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);
-  virtual ~HistogramBase();
-
-  const char* histogram_name() const { return histogram_name_; }
-
-  // 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
-  // in more compact machine code being generated by the macros.
-  virtual void CheckName(const StringPiece& name) const;
-
-  // Get a unique ID for this histogram's samples.
-  virtual uint64_t name_hash() const = 0;
-
-  // Operations with Flags enum.
-  int32_t flags() const { return subtle::NoBarrier_Load(&flags_); }
-  void SetFlags(int32_t flags);
-  void ClearFlags(int32_t flags);
-
-  virtual HistogramType GetHistogramType() const = 0;
-
-  // Whether the histogram has construction arguments as parameters specified.
-  // For histograms that don't have the concept of minimum, maximum or
-  // bucket_count, this function always returns false.
-  virtual bool HasConstructionArguments(
-      Sample expected_minimum,
-      Sample expected_maximum,
-      uint32_t expected_bucket_count) const = 0;
-
-  virtual void Add(Sample value) = 0;
-
-  // In Add function the |value| bucket is increased by one, but in some use
-  // cases we need to increase this value by an arbitrary integer. AddCount
-  // function increases the |value| bucket by |count|. |count| should be greater
-  // than or equal to 1.
-  virtual void AddCount(Sample value, int count) = 0;
-
-  // Similar to above but divides |count| by the |scale| amount. Probabilistic
-  // rounding is used to yield a reasonably accurate total when many samples
-  // are added. Methods for common cases of scales 1000 and 1024 are included.
-  void AddScaled(Sample value, int count, int scale);
-  void AddKilo(Sample value, int count);  // scale=1000
-  void AddKiB(Sample value, int count);   // scale=1024
-
-  // Convenient functions that call Add(Sample).
-  void AddTime(const TimeDelta& time) { AddTimeMillisecondsGranularity(time); }
-  void AddTimeMillisecondsGranularity(const TimeDelta& time);
-  // Note: AddTimeMicrosecondsGranularity() drops the report if this client
-  // doesn't have a high-resolution clock.
-  void AddTimeMicrosecondsGranularity(const TimeDelta& time);
-  void AddBoolean(bool value);
-
-  virtual void AddSamples(const HistogramSamples& samples) = 0;
-  virtual bool AddSamplesFromPickle(base::PickleIterator* iter) = 0;
-
-  // Serialize the histogram info into |pickle|.
-  // Note: This only serializes the construction arguments of the histogram, but
-  // does not serialize the samples.
-  void SerializeInfo(base::Pickle* pickle) const;
-
-  // Try to find out data corruption from histogram and the samples.
-  // The returned value is a combination of Inconsistency enum.
-  virtual uint32_t FindCorruption(const HistogramSamples& samples) const;
-
-  // Snapshot the current complete set of sample data.
-  // Override with atomic/locked snapshot if needed.
-  // NOTE: this data can overflow for long-running sessions. It should be
-  // handled with care and this method is recommended to be used only
-  // in about:histograms and test code.
-  virtual std::unique_ptr<HistogramSamples> SnapshotSamples() const = 0;
-
-  // Calculate the change (delta) in histogram counts since the previous call
-  // to this method. Each successive call will return only those counts
-  // changed since the last call.
-  virtual std::unique_ptr<HistogramSamples> SnapshotDelta() = 0;
-
-  // Calculate the change (delta) in histogram counts since the previous call
-  // to SnapshotDelta() but do so without modifying any internal data as to
-  // what was previous logged. After such a call, no further calls to this
-  // method or to SnapshotDelta() should be done as the result would include
-  // data previously returned. Because no internal data is changed, this call
-  // can be made on "const" histograms such as those with data held in
-  // read-only memory.
-  virtual std::unique_ptr<HistogramSamples> SnapshotFinalDelta() const = 0;
-
-  // The following methods provide graphical histogram displays.
-  virtual void WriteHTMLGraph(std::string* output) const = 0;
-  virtual void WriteAscii(std::string* output) const = 0;
-
-  // TODO(bcwhite): Remove this after https://crbug/836875.
-  virtual void ValidateHistogramContents() const;
-
-  // Produce a JSON representation of the histogram with |verbosity_level| as
-  // the serialization verbosity. This is implemented with the help of
-  // GetParameters and GetCountAndBucketData; overwrite them to customize the
-  // output.
-  void WriteJSON(std::string* output, JSONVerbosityLevel verbosity_level) const;
-
- protected:
-  enum ReportActivity { HISTOGRAM_CREATED, HISTOGRAM_LOOKUP };
-
-  // Subclasses should implement this function to make SerializeInfo work.
-  virtual void SerializeInfoImpl(base::Pickle* pickle) const = 0;
-
-  // Writes information about the construction parameters in |params|.
-  virtual void GetParameters(DictionaryValue* params) const = 0;
-
-  // Writes information about the current (non-empty) buckets and their sample
-  // counts to |buckets|, the total sample count to |count| and the total sum
-  // to |sum|.
-  virtual void GetCountAndBucketData(Count* count,
-                                     int64_t* sum,
-                                     ListValue* buckets) const = 0;
-
-  //// Produce actual graph (set of blank vs non blank char's) for a bucket.
-  void WriteAsciiBucketGraph(double current_size,
-                             double max_size,
-                             std::string* output) const;
-
-  // Return a string description of what goes in a given bucket.
-  const std::string GetSimpleAsciiBucketRange(Sample sample) const;
-
-  // Write textual description of the bucket contents (relative to histogram).
-  // Output is the count in the buckets, as well as the percentage.
-  void WriteAsciiBucketValue(Count current,
-                             double scaled_sum,
-                             std::string* output) const;
-
-  // Retrieves the callback for this histogram, if one exists, and runs it
-  // passing |sample| as the parameter.
-  void FindAndRunCallback(Sample 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(const std::string& name);
-
- private:
-  friend class HistogramBaseTest;
-
-  // 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 StringPiece because (a) char*
-  // is 1/2 the size and (b) StringPiece 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.
-  const char* const histogram_name_;
-
-  // Additional information about the histogram.
-  AtomicCount flags_;
-
-  DISALLOW_COPY_AND_ASSIGN(HistogramBase);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_HISTOGRAM_BASE_H_
diff --git a/base/metrics/histogram_delta_serialization.cc b/base/metrics/histogram_delta_serialization.cc
deleted file mode 100644
index a74b87f..0000000
--- a/base/metrics/histogram_delta_serialization.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/histogram_delta_serialization.h"
-
-#include "base/logging.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_snapshot_manager.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/pickle.h"
-#include "base/values.h"
-
-namespace base {
-
-namespace {
-
-// Create or find existing histogram and add the samples from pickle.
-// Silently returns when seeing any data problem in the pickle.
-void DeserializeHistogramAndAddSamples(PickleIterator* iter) {
-  HistogramBase* histogram = DeserializeHistogramInfo(iter);
-  if (!histogram)
-    return;
-
-  if (histogram->flags() & HistogramBase::kIPCSerializationSourceFlag) {
-    DVLOG(1) << "Single process mode, histogram observed and not copied: "
-             << histogram->histogram_name();
-    return;
-  }
-  histogram->AddSamplesFromPickle(iter);
-}
-
-}  // namespace
-
-HistogramDeltaSerialization::HistogramDeltaSerialization(
-    const std::string& caller_name)
-    : histogram_snapshot_manager_(this), serialized_deltas_(nullptr) {}
-
-HistogramDeltaSerialization::~HistogramDeltaSerialization() = default;
-
-void HistogramDeltaSerialization::PrepareAndSerializeDeltas(
-    std::vector<std::string>* serialized_deltas,
-    bool include_persistent) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  serialized_deltas_ = serialized_deltas;
-  // Note: Before serializing, we set the kIPCSerializationSourceFlag for all
-  // the histograms, so that the receiving process can distinguish them from the
-  // local histograms.
-  StatisticsRecorder::PrepareDeltas(
-      include_persistent, Histogram::kIPCSerializationSourceFlag,
-      Histogram::kNoFlags, &histogram_snapshot_manager_);
-  serialized_deltas_ = nullptr;
-}
-
-// static
-void HistogramDeltaSerialization::DeserializeAndAddSamples(
-    const std::vector<std::string>& serialized_deltas) {
-  for (std::vector<std::string>::const_iterator it = serialized_deltas.begin();
-       it != serialized_deltas.end(); ++it) {
-    Pickle pickle(it->data(), checked_cast<int>(it->size()));
-    PickleIterator iter(pickle);
-    DeserializeHistogramAndAddSamples(&iter);
-  }
-}
-
-void HistogramDeltaSerialization::RecordDelta(
-    const HistogramBase& histogram,
-    const HistogramSamples& snapshot) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK_NE(0, snapshot.TotalCount());
-
-  Pickle pickle;
-  histogram.SerializeInfo(&pickle);
-  snapshot.Serialize(&pickle);
-  serialized_deltas_->push_back(
-      std::string(static_cast<const char*>(pickle.data()), pickle.size()));
-}
-
-}  // namespace base
diff --git a/base/metrics/histogram_delta_serialization.h b/base/metrics/histogram_delta_serialization.h
deleted file mode 100644
index 57ebd2c..0000000
--- a/base/metrics/histogram_delta_serialization.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_DELTA_SERIALIZATION_H_
-#define BASE_METRICS_HISTOGRAM_DELTA_SERIALIZATION_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/metrics/histogram_flattener.h"
-#include "base/metrics/histogram_snapshot_manager.h"
-#include "base/threading/thread_checker.h"
-
-namespace base {
-
-class HistogramBase;
-
-// Serializes and restores histograms deltas.
-class BASE_EXPORT HistogramDeltaSerialization : public HistogramFlattener {
- public:
-  // |caller_name| is string used in histograms for counting inconsistencies.
-  explicit HistogramDeltaSerialization(const std::string& caller_name);
-  ~HistogramDeltaSerialization() override;
-
-  // Computes deltas in histogram bucket counts relative to the previous call to
-  // this method. Stores the deltas in serialized form into |serialized_deltas|.
-  // If |serialized_deltas| is null, no data is serialized, though the next call
-  // will compute the deltas relative to this one. Setting |include_persistent|
-  // will include histograms held in persistent memory (and thus may be reported
-  // elsewhere); otherwise only histograms local to this process are serialized.
-  void PrepareAndSerializeDeltas(std::vector<std::string>* serialized_deltas,
-                                 bool include_persistent);
-
-  // Deserialize deltas and add samples to corresponding histograms, creating
-  // them if necessary. Silently ignores errors in |serialized_deltas|.
-  static void DeserializeAndAddSamples(
-      const std::vector<std::string>& serialized_deltas);
-
- private:
-  // HistogramFlattener implementation.
-  void RecordDelta(const HistogramBase& histogram,
-                   const HistogramSamples& snapshot) override;
-
-  ThreadChecker thread_checker_;
-
-  // Calculates deltas in histogram counters.
-  HistogramSnapshotManager histogram_snapshot_manager_;
-
-  // Output buffer for serialized deltas.
-  std::vector<std::string>* serialized_deltas_;
-
-  DISALLOW_COPY_AND_ASSIGN(HistogramDeltaSerialization);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_HISTOGRAM_DELTA_SERIALIZATION_H_
diff --git a/base/metrics/histogram_flattener.h b/base/metrics/histogram_flattener.h
deleted file mode 100644
index 6a5e3f4..0000000
--- a/base/metrics/histogram_flattener.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_FLATTENER_H_
-#define BASE_METRICS_HISTOGRAM_FLATTENER_H_
-
-#include <map>
-#include <string>
-
-#include "base/macros.h"
-#include "base/metrics/histogram.h"
-
-namespace base {
-
-class HistogramSamples;
-
-// HistogramFlattener is an interface used by HistogramSnapshotManager, which
-// handles the logistics of gathering up available histograms for recording.
-class BASE_EXPORT HistogramFlattener {
- public:
-  virtual void RecordDelta(const HistogramBase& histogram,
-                           const HistogramSamples& snapshot) = 0;
-
- protected:
-  HistogramFlattener() = default;
-  virtual ~HistogramFlattener() = default;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(HistogramFlattener);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_HISTOGRAM_FLATTENER_H_
diff --git a/base/metrics/histogram_functions.cc b/base/metrics/histogram_functions.cc
deleted file mode 100644
index 31bf219..0000000
--- a/base/metrics/histogram_functions.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/histogram_functions.h"
-
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/time/time.h"
-
-namespace base {
-
-void UmaHistogramBoolean(const std::string& name, bool sample) {
-  HistogramBase* histogram = BooleanHistogram::FactoryGet(
-      name, HistogramBase::kUmaTargetedHistogramFlag);
-  histogram->Add(sample);
-}
-
-void UmaHistogramExactLinear(const std::string& name,
-                             int sample,
-                             int value_max) {
-  HistogramBase* histogram =
-      LinearHistogram::FactoryGet(name, 1, value_max, value_max + 1,
-                                  HistogramBase::kUmaTargetedHistogramFlag);
-  histogram->Add(sample);
-}
-
-void UmaHistogramPercentage(const std::string& name, int percent) {
-  UmaHistogramExactLinear(name, percent, 100);
-}
-
-void UmaHistogramCustomCounts(const std::string& name,
-                              int sample,
-                              int min,
-                              int max,
-                              int buckets) {
-  HistogramBase* histogram = Histogram::FactoryGet(
-      name, min, max, buckets, HistogramBase::kUmaTargetedHistogramFlag);
-  histogram->Add(sample);
-}
-
-void UmaHistogramCounts100(const std::string& name, int sample) {
-  UmaHistogramCustomCounts(name, sample, 1, 100, 50);
-}
-
-void UmaHistogramCounts1000(const std::string& name, int sample) {
-  UmaHistogramCustomCounts(name, sample, 1, 1000, 50);
-}
-
-void UmaHistogramCounts10000(const std::string& name, int sample) {
-  UmaHistogramCustomCounts(name, sample, 1, 10000, 50);
-}
-
-void UmaHistogramCounts100000(const std::string& name, int sample) {
-  UmaHistogramCustomCounts(name, sample, 1, 100000, 50);
-}
-
-void UmaHistogramCounts1M(const std::string& name, int sample) {
-  UmaHistogramCustomCounts(name, sample, 1, 1000000, 50);
-}
-
-void UmaHistogramCounts10M(const std::string& name, int sample) {
-  UmaHistogramCustomCounts(name, sample, 1, 10000000, 50);
-}
-
-void UmaHistogramCustomTimes(const std::string& name,
-                             TimeDelta sample,
-                             TimeDelta min,
-                             TimeDelta max,
-                             int buckets) {
-  HistogramBase* histogram = Histogram::FactoryTimeGet(
-      name, min, max, buckets, HistogramBase::kUmaTargetedHistogramFlag);
-  histogram->AddTimeMillisecondsGranularity(sample);
-}
-
-void UmaHistogramTimes(const std::string& name, TimeDelta sample) {
-  UmaHistogramCustomTimes(name, sample, TimeDelta::FromMilliseconds(1),
-                          TimeDelta::FromSeconds(10), 50);
-}
-
-void UmaHistogramMediumTimes(const std::string& name, TimeDelta sample) {
-  UmaHistogramCustomTimes(name, sample, TimeDelta::FromMilliseconds(1),
-                          TimeDelta::FromMinutes(3), 50);
-}
-
-void UmaHistogramLongTimes(const std::string& name, TimeDelta sample) {
-  UmaHistogramCustomTimes(name, sample, TimeDelta::FromMilliseconds(1),
-                          TimeDelta::FromHours(1), 50);
-}
-
-void UmaHistogramMemoryKB(const std::string& name, int sample) {
-  UmaHistogramCustomCounts(name, sample, 1000, 500000, 50);
-}
-
-void UmaHistogramMemoryMB(const std::string& name, int sample) {
-  UmaHistogramCustomCounts(name, sample, 1, 1000, 50);
-}
-
-void UmaHistogramMemoryLargeMB(const std::string& name, int sample) {
-  UmaHistogramCustomCounts(name, sample, 1, 64000, 100);
-}
-
-void UmaHistogramSparse(const std::string& name, int sample) {
-  HistogramBase* histogram = SparseHistogram::FactoryGet(
-      name, HistogramBase::kUmaTargetedHistogramFlag);
-  histogram->Add(sample);
-}
-
-}  // namespace base
diff --git a/base/metrics/histogram_functions.h b/base/metrics/histogram_functions.h
deleted file mode 100644
index 60c0057..0000000
--- a/base/metrics/histogram_functions.h
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_FUNCTIONS_H_
-#define BASE_METRICS_HISTOGRAM_FUNCTIONS_H_
-
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_base.h"
-#include "base/time/time.h"
-
-// Functions for recording metrics.
-//
-// For best practices on deciding when to emit to a histogram and what form
-// the histogram should take, see
-// https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md
-
-// Functions for recording UMA histograms. These can be used for cases
-// when the histogram name is generated at runtime. The functionality is
-// equivalent to macros defined in histogram_macros.h but allowing non-constant
-// histogram names. These functions are slower compared to their macro
-// equivalent because the histogram objects are not cached between calls.
-// So, these shouldn't be used in performance critical code.
-namespace base {
-
-// For histograms with linear buckets.
-// Used for capturing integer data with a linear bucketing scheme. This can be
-// used when you want the exact value of some small numeric count, with a max of
-// 100 or less. If you need to capture a range of greater than 100, we recommend
-// the use of the COUNT histograms below.
-// Sample usage:
-//   base::UmaHistogramExactLinear("Histogram.Linear", some_value, 10);
-BASE_EXPORT void UmaHistogramExactLinear(const std::string& name,
-                                         int sample,
-                                         int value_max);
-
-// For adding a sample to an enumerated histogram.
-// Sample usage:
-//   // These values are persisted to logs. Entries should not be renumbered and
-//   // numeric values should never be reused.
-//   enum class MyEnum {
-//     FIRST_VALUE = 0,
-//     SECOND_VALUE = 1,
-//     ...
-//     FINAL_VALUE = N,
-//     COUNT
-//   };
-//   base::UmaHistogramEnumeration("My.Enumeration",
-//                                 MyEnum::SOME_VALUE, MyEnum::COUNT);
-//
-// Note: The value in |sample| must be strictly less than |enum_size|.
-template <typename T>
-void UmaHistogramEnumeration(const std::string& name, T sample, T enum_size) {
-  static_assert(std::is_enum<T>::value,
-                "Non enum passed to UmaHistogramEnumeration");
-  DCHECK_LE(static_cast<uintmax_t>(enum_size), static_cast<uintmax_t>(INT_MAX));
-  DCHECK_LT(static_cast<uintmax_t>(sample), static_cast<uintmax_t>(enum_size));
-  return UmaHistogramExactLinear(name, static_cast<int>(sample),
-                                 static_cast<int>(enum_size));
-}
-
-// Same as above, but uses T::kMaxValue as the inclusive maximum value of the
-// enum.
-template <typename T>
-void UmaHistogramEnumeration(const std::string& name, T sample) {
-  static_assert(std::is_enum<T>::value,
-                "Non enum passed to UmaHistogramEnumeration");
-  DCHECK_LE(static_cast<uintmax_t>(T::kMaxValue),
-            static_cast<uintmax_t>(INT_MAX) - 1);
-  DCHECK_LE(static_cast<uintmax_t>(sample),
-            static_cast<uintmax_t>(T::kMaxValue));
-  return UmaHistogramExactLinear(name, static_cast<int>(sample),
-                                 static_cast<int>(T::kMaxValue) + 1);
-}
-
-// For adding boolean sample to histogram.
-// Sample usage:
-//   base::UmaHistogramBoolean("My.Boolean", true)
-BASE_EXPORT void UmaHistogramBoolean(const std::string& name, bool sample);
-
-// For adding histogram with percent.
-// Percents are integer between 1 and 100.
-// Sample usage:
-//   base::UmaHistogramPercentage("My.Percent", 69)
-BASE_EXPORT void UmaHistogramPercentage(const std::string& name, int percent);
-
-// For adding counts histogram.
-// Sample usage:
-//   base::UmaHistogramCustomCounts("My.Counts", some_value, 1, 600, 30)
-BASE_EXPORT void UmaHistogramCustomCounts(const std::string& name,
-                                          int sample,
-                                          int min,
-                                          int max,
-                                          int buckets);
-
-// Counts specialization for maximum counts 100, 1000, 10k, 100k, 1M and 10M.
-BASE_EXPORT void UmaHistogramCounts100(const std::string& name, int sample);
-BASE_EXPORT void UmaHistogramCounts1000(const std::string& name, int sample);
-BASE_EXPORT void UmaHistogramCounts10000(const std::string& name, int sample);
-BASE_EXPORT void UmaHistogramCounts100000(const std::string& name, int sample);
-BASE_EXPORT void UmaHistogramCounts1M(const std::string& name, int sample);
-BASE_EXPORT void UmaHistogramCounts10M(const std::string& name, int sample);
-
-// For histograms storing times.
-BASE_EXPORT void UmaHistogramCustomTimes(const std::string& name,
-                                         TimeDelta sample,
-                                         TimeDelta min,
-                                         TimeDelta max,
-                                         int buckets);
-// For short timings from 1 ms up to 10 seconds (50 buckets).
-BASE_EXPORT void UmaHistogramTimes(const std::string& name, TimeDelta sample);
-// For medium timings up to 3 minutes (50 buckets).
-BASE_EXPORT void UmaHistogramMediumTimes(const std::string& name,
-                                         TimeDelta sample);
-// For time intervals up to 1 hr (50 buckets).
-BASE_EXPORT void UmaHistogramLongTimes(const std::string& name,
-                                       TimeDelta sample);
-
-// For recording memory related histograms.
-// Used to measure common KB-granularity memory stats. Range is up to 500M.
-BASE_EXPORT void UmaHistogramMemoryKB(const std::string& name, int sample);
-// Used to measure common MB-granularity memory stats. Range is up to ~1G.
-BASE_EXPORT void UmaHistogramMemoryMB(const std::string& name, int sample);
-// Used to measure common MB-granularity memory stats. Range is up to ~64G.
-BASE_EXPORT void UmaHistogramMemoryLargeMB(const std::string& name, int sample);
-
-// For recording sparse histograms.
-// The |sample| can be a negative or non-negative number.
-//
-// Sparse histograms are well suited for recording counts of exact sample values
-// that are sparsely distributed over a relatively large range, in cases where
-// ultra-fast performance is not critical. For instance, Sqlite.Version.* are
-// sparse because for any given database, there's going to be exactly one
-// version logged.
-//
-// Performance:
-// ------------
-// Sparse histograms are typically more memory-efficient but less time-efficient
-// than other histograms. Essentially, they sparse histograms use a map rather
-// than a vector for their backing storage; they also require lock acquisition
-// to increment a sample, whereas other histogram do not. Hence, each increment
-// operation is a bit slower than for other histograms. But, if the data is
-// sparse, then they use less memory client-side, because they allocate buckets
-// on demand rather than preallocating.
-//
-// Data size:
-// ----------
-// Note that server-side, we still need to load all buckets, across all users,
-// at once. Thus, please avoid exploding such histograms, i.e. uploading many
-// many distinct values to the server (across all users). Concretely, keep the
-// number of distinct values <= 100 ideally, definitely <= 1000. If you have no
-// guarantees on the range of your data, use clamping, e.g.:
-//   UmaHistogramSparse("MyHistogram", ClampToRange(value, 0, 200));
-BASE_EXPORT void UmaHistogramSparse(const std::string& name, int sample);
-
-}  // namespace base
-
-#endif  // BASE_METRICS_HISTOGRAM_FUNCTIONS_H_
diff --git a/base/metrics/histogram_macros.h b/base/metrics/histogram_macros.h
deleted file mode 100644
index 0960b19..0000000
--- a/base/metrics/histogram_macros.h
+++ /dev/null
@@ -1,359 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_MACROS_H_
-#define BASE_METRICS_HISTOGRAM_MACROS_H_
-
-#include "base/macros.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_macros_internal.h"
-#include "base/metrics/histogram_macros_local.h"
-#include "base/time/time.h"
-
-
-// Macros for efficient use of histograms.
-//
-// For best practices on deciding when to emit to a histogram and what form
-// the histogram should take, see
-// https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/histograms/README.md
-
-// TODO(rkaplow): Link to proper documentation on metric creation once we have
-// it in a good state.
-
-// All of these macros must be called with |name| as a runtime constant - it
-// doesn't have to literally be a constant, but it must be the same string on
-// all calls from a particular call site. If this rule is violated, it is
-// possible the data will be written to the wrong histogram.
-
-//------------------------------------------------------------------------------
-// Enumeration histograms.
-
-// These macros create histograms for enumerated data. Ideally, the data should
-// be of the form of "event occurs, log the result". We recommended not putting
-// related but not directly connected data as enums within the same histogram.
-// You should be defining an associated Enum, and the input sample should be
-// an element of the Enum.
-// All of these macros must be called with |name| as a runtime constant.
-
-// The first variant of UMA_HISTOGRAM_ENUMERATION accepts two arguments: the
-// histogram name and the enum sample. It deduces the correct boundary value to
-// use by looking for an enumerator with the name kMaxValue. kMaxValue should
-// share the value of the highest enumerator: this avoids switch statements
-// having to handle a sentinel no-op value.
-//
-// Sample usage:
-//   // These values are persisted to logs. Entries should not be renumbered and
-//   // numeric values should never be reused.
-//   enum class MyEnum {
-//     kFirstValue = 0,
-//     kSecondValue = 1,
-//     ...
-//     kFinalValue = N,
-//     kMaxValue = kFinalValue,
-//   };
-//   UMA_HISTOGRAM_ENUMERATION("My.Enumeration", MyEnum::kSomeValue);
-//
-// The second variant requires three arguments: the first two are the same as
-// before, and the third argument is the enum boundary: this must be strictly
-// greater than any other enumerator that will be sampled.
-//
-// Sample usage:
-//   // These values are persisted to logs. Entries should not be renumbered and
-//   // numeric values should never be reused.
-//   enum class MyEnum {
-//     FIRST_VALUE = 0,
-//     SECOND_VALUE = 1,
-//     ...
-//     FINAL_VALUE = N,
-//     COUNT
-//   };
-//   UMA_HISTOGRAM_ENUMERATION("My.Enumeration",
-//                             MyEnum::SOME_VALUE, MyEnum::COUNT);
-//
-// Note: If the enum is used in a switch, it is often desirable to avoid writing
-// a case statement to handle an unused sentinel value (i.e. COUNT in the above
-// example). For scoped enums, this is awkward since it requires casting the
-// enum to an arithmetic type and adding one. Instead, prefer the two argument
-// version of the macro which automatically deduces the boundary from kMaxValue.
-#define UMA_HISTOGRAM_ENUMERATION(name, ...)                            \
-  CR_EXPAND_ARG(INTERNAL_UMA_HISTOGRAM_ENUMERATION_GET_MACRO(           \
-      __VA_ARGS__, INTERNAL_UMA_HISTOGRAM_ENUMERATION_SPECIFY_BOUNDARY, \
-      INTERNAL_UMA_HISTOGRAM_ENUMERATION_DEDUCE_BOUNDARY)(              \
-      name, __VA_ARGS__, base::HistogramBase::kUmaTargetedHistogramFlag))
-
-// Histogram for boolean values.
-
-// Sample usage:
-//   UMA_HISTOGRAM_BOOLEAN("Histogram.Boolean", bool);
-#define UMA_HISTOGRAM_BOOLEAN(name, sample)                                    \
-    STATIC_HISTOGRAM_POINTER_BLOCK(name, AddBoolean(sample),                   \
-        base::BooleanHistogram::FactoryGet(name,                               \
-            base::HistogramBase::kUmaTargetedHistogramFlag))
-
-//------------------------------------------------------------------------------
-// Linear histograms.
-
-// All of these macros must be called with |name| as a runtime constant.
-
-// Used for capturing integer data with a linear bucketing scheme. This can be
-// used when you want the exact value of some small numeric count, with a max of
-// 100 or less. If you need to capture a range of greater than 100, we recommend
-// the use of the COUNT histograms below.
-
-// Sample usage:
-//   UMA_HISTOGRAM_EXACT_LINEAR("Histogram.Linear", count, 10);
-#define UMA_HISTOGRAM_EXACT_LINEAR(name, sample, value_max) \
-  INTERNAL_HISTOGRAM_EXACT_LINEAR_WITH_FLAG(                \
-      name, sample, value_max, base::HistogramBase::kUmaTargetedHistogramFlag)
-
-// Used for capturing basic percentages. This will be 100 buckets of size 1.
-
-// Sample usage:
-//   UMA_HISTOGRAM_PERCENTAGE("Histogram.Percent", percent_as_int);
-#define UMA_HISTOGRAM_PERCENTAGE(name, percent_as_int) \
-  UMA_HISTOGRAM_EXACT_LINEAR(name, percent_as_int, 101)
-
-//------------------------------------------------------------------------------
-// Count histograms. These are used for collecting numeric data. Note that we
-// have macros for more specialized use cases below (memory, time, percentages).
-
-// The number suffixes here refer to the max size of the sample, i.e. COUNT_1000
-// will be able to collect samples of counts up to 1000. The default number of
-// buckets in all default macros is 50. We recommend erring on the side of too
-// large a range versus too short a range.
-// These macros default to exponential histograms - i.e. the lengths of the
-// bucket ranges exponentially increase as the sample range increases.
-// These should *not* be used if you are interested in exact counts, i.e. a
-// bucket range of 1. In these cases, you should use the ENUMERATION macros
-// defined later. These should also not be used to capture the number of some
-// event, i.e. "button X was clicked N times". In this cases, an enum should be
-// used, ideally with an appropriate baseline enum entry included.
-// All of these macros must be called with |name| as a runtime constant.
-
-// Sample usage:
-//   UMA_HISTOGRAM_COUNTS_1M("My.Histogram", sample);
-
-#define UMA_HISTOGRAM_COUNTS_100(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS(    \
-    name, sample, 1, 100, 50)
-
-#define UMA_HISTOGRAM_COUNTS_1000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS(   \
-    name, sample, 1, 1000, 50)
-
-#define UMA_HISTOGRAM_COUNTS_10000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS(  \
-    name, sample, 1, 10000, 50)
-
-#define UMA_HISTOGRAM_COUNTS_100000(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS( \
-    name, sample, 1, 100000, 50)
-
-#define UMA_HISTOGRAM_COUNTS_1M(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS(     \
-    name, sample, 1, 1000000, 50)
-
-#define UMA_HISTOGRAM_COUNTS_10M(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS(    \
-    name, sample, 1, 10000000, 50)
-
-// This can be used when the default ranges are not sufficient. This macro lets
-// the metric developer customize the min and max of the sampled range, as well
-// as the number of buckets recorded.
-// Any data outside the range here will be put in underflow and overflow
-// buckets. Min values should be >=1 as emitted 0s will still go into the
-// underflow bucket.
-
-// Sample usage:
-//   UMA_HISTOGRAM_CUSTOM_COUNTS("My.Histogram", 1, 100000000, 100);
-#define UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count)      \
-    INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG(                                \
-        name, sample, min, max, bucket_count,                                  \
-        base::HistogramBase::kUmaTargetedHistogramFlag)
-
-//------------------------------------------------------------------------------
-// Timing histograms. These are used for collecting timing data (generally
-// latencies).
-
-// These macros create exponentially sized histograms (lengths of the bucket
-// ranges exponentially increase as the sample range increases). The input
-// sample is a base::TimeDelta. The output data is measured in ms granularity.
-// All of these macros must be called with |name| as a runtime constant.
-
-// Sample usage:
-//   UMA_HISTOGRAM_TIMES("My.Timing.Histogram", time_delta);
-
-// Short timings - up to 10 seconds. For high-resolution (microseconds) timings,
-// see UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES.
-#define UMA_HISTOGRAM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES(          \
-    name, sample, base::TimeDelta::FromMilliseconds(1),                        \
-    base::TimeDelta::FromSeconds(10), 50)
-
-// Medium timings - up to 3 minutes. Note this starts at 10ms (no good reason,
-// but not worth changing).
-#define UMA_HISTOGRAM_MEDIUM_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES(   \
-    name, sample, base::TimeDelta::FromMilliseconds(10),                       \
-    base::TimeDelta::FromMinutes(3), 50)
-
-// Long timings - up to an hour.
-#define UMA_HISTOGRAM_LONG_TIMES(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES(     \
-    name, sample, base::TimeDelta::FromMilliseconds(1),                        \
-    base::TimeDelta::FromHours(1), 50)
-
-// Long timings with higher granularity - up to an hour with 100 buckets.
-#define UMA_HISTOGRAM_LONG_TIMES_100(name, sample) UMA_HISTOGRAM_CUSTOM_TIMES( \
-    name, sample, base::TimeDelta::FromMilliseconds(1),                        \
-    base::TimeDelta::FromHours(1), 100)
-
-// This can be used when the default ranges are not sufficient. This macro lets
-// the metric developer customize the min and max of the sampled range, as well
-// as the number of buckets recorded.
-
-// Sample usage:
-//   UMA_HISTOGRAM_CUSTOM_TIMES("Very.Long.Timing.Histogram", time_delta,
-//       base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 100);
-#define UMA_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \
-  STATIC_HISTOGRAM_POINTER_BLOCK(                                        \
-      name, AddTimeMillisecondsGranularity(sample),                      \
-      base::Histogram::FactoryTimeGet(                                   \
-          name, min, max, bucket_count,                                  \
-          base::HistogramBase::kUmaTargetedHistogramFlag))
-
-// Same as UMA_HISTOGRAM_CUSTOM_TIMES but reports |sample| in microseconds,
-// dropping the report if this client doesn't have a high-resolution clock.
-//
-// Note: dropping reports on clients with low-resolution clocks means these
-// reports will be biased to a portion of the population on Windows. See
-// Windows.HasHighResolutionTimeTicks for the affected sample.
-//
-// Sample usage:
-//  UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(
-//      "High.Resolution.TimingMicroseconds.Histogram", time_delta,
-//      base::TimeDelta::FromMicroseconds(1),
-//      base::TimeDelta::FromMilliseconds(10), 100);
-#define UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES(name, sample, min, max, \
-                                                bucket_count)           \
-  STATIC_HISTOGRAM_POINTER_BLOCK(                                       \
-      name, AddTimeMicrosecondsGranularity(sample),                     \
-      base::Histogram::FactoryMicrosecondsTimeGet(                      \
-          name, min, max, bucket_count,                                 \
-          base::HistogramBase::kUmaTargetedHistogramFlag))
-
-// Scoped class which logs its time on this earth as a UMA statistic. This is
-// recommended for when you want a histogram which measures the time it takes
-// for a method to execute. This measures up to 10 seconds. It uses
-// UMA_HISTOGRAM_TIMES under the hood.
-
-// Sample usage:
-//   void Function() {
-//     SCOPED_UMA_HISTOGRAM_TIMER("Component.FunctionTime");
-//     ...
-//   }
-#define SCOPED_UMA_HISTOGRAM_TIMER(name)                                       \
-  INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, false, __COUNTER__)
-
-// Similar scoped histogram timer, but this uses UMA_HISTOGRAM_LONG_TIMES_100,
-// which measures up to an hour, and uses 100 buckets. This is more expensive
-// to store, so only use if this often takes >10 seconds.
-#define SCOPED_UMA_HISTOGRAM_LONG_TIMER(name)                                  \
-  INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, true, __COUNTER__)
-
-
-//------------------------------------------------------------------------------
-// Memory histograms.
-
-// These macros create exponentially sized histograms (lengths of the bucket
-// ranges exponentially increase as the sample range increases). The input
-// sample must be a number measured in kilobytes.
-// All of these macros must be called with |name| as a runtime constant.
-
-// Sample usage:
-//   UMA_HISTOGRAM_MEMORY_KB("My.Memory.Histogram", memory_in_kb);
-
-// Used to measure common KB-granularity memory stats. Range is up to 500000KB -
-// approximately 500M.
-#define UMA_HISTOGRAM_MEMORY_KB(name, sample)                                  \
-    UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1000, 500000, 50)
-
-// Used to measure common MB-granularity memory stats. Range is up to ~64G.
-#define UMA_HISTOGRAM_MEMORY_LARGE_MB(name, sample)                            \
-    UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 64000, 100)
-
-
-//------------------------------------------------------------------------------
-// Stability-specific histograms.
-
-// Histograms logged in as stability histograms will be included in the initial
-// stability log. See comments by declaration of
-// MetricsService::PrepareInitialStabilityLog().
-// All of these macros must be called with |name| as a runtime constant.
-
-// For details on usage, see the documentation on the non-stability equivalents.
-
-#define UMA_STABILITY_HISTOGRAM_COUNTS_100(name, sample)                       \
-    UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 100, 50)
-
-#define UMA_STABILITY_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max,          \
-                                              bucket_count)                    \
-    INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG(                                \
-        name, sample, min, max, bucket_count,                                  \
-        base::HistogramBase::kUmaStabilityHistogramFlag)
-
-#define UMA_STABILITY_HISTOGRAM_ENUMERATION(name, sample, enum_max)            \
-    INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG(                                  \
-        name, sample, enum_max,                                                \
-        base::HistogramBase::kUmaStabilityHistogramFlag)
-
-//------------------------------------------------------------------------------
-// Histogram instantiation helpers.
-
-// Support a collection of histograms, perhaps one for each entry in an
-// enumeration. This macro manages a block of pointers, adding to a specific
-// one by its index.
-//
-// A typical instantiation looks something like this:
-//  STATIC_HISTOGRAM_POINTER_GROUP(
-//      GetHistogramNameForIndex(histogram_index),
-//      histogram_index, MAXIMUM_HISTOGRAM_INDEX, Add(some_delta),
-//      base::Histogram::FactoryGet(
-//          GetHistogramNameForIndex(histogram_index),
-//          MINIMUM_SAMPLE, MAXIMUM_SAMPLE, BUCKET_COUNT,
-//          base::HistogramBase::kUmaTargetedHistogramFlag));
-//
-// Though it seems inefficient to generate the name twice, the first
-// instance will be used only for DCHECK builds and the second will
-// execute only during the first access to the given index, after which
-// the pointer is cached and the name never needed again.
-#define STATIC_HISTOGRAM_POINTER_GROUP(constant_histogram_name, index,        \
-                                       constant_maximum,                      \
-                                       histogram_add_method_invocation,       \
-                                       histogram_factory_get_invocation)      \
-  do {                                                                        \
-    static base::subtle::AtomicWord atomic_histograms[constant_maximum];      \
-    DCHECK_LE(0, index);                                                      \
-    DCHECK_LT(index, constant_maximum);                                       \
-    HISTOGRAM_POINTER_USE(&atomic_histograms[index], constant_histogram_name, \
-                          histogram_add_method_invocation,                    \
-                          histogram_factory_get_invocation);                  \
-  } while (0)
-
-//------------------------------------------------------------------------------
-// Deprecated histogram macros. Not recommended for current use.
-
-// Legacy name for UMA_HISTOGRAM_COUNTS_1M. Suggest using explicit naming
-// and not using this macro going forward.
-#define UMA_HISTOGRAM_COUNTS(name, sample) UMA_HISTOGRAM_CUSTOM_COUNTS(        \
-    name, sample, 1, 1000000, 50)
-
-// MB-granularity memory metric. This has a short max (1G).
-#define UMA_HISTOGRAM_MEMORY_MB(name, sample)                                  \
-    UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000, 50)
-
-// For an enum with customized range. In general, sparse histograms should be
-// used instead.
-// Samples should be one of the std::vector<int> list provided via
-// |custom_ranges|. See comments above CustomRanges::FactoryGet about the
-// requirement of |custom_ranges|. You can use the helper function
-// CustomHistogram::ArrayToCustomEnumRanges to transform a C-style array of
-// valid sample values to a std::vector<int>.
-#define UMA_HISTOGRAM_CUSTOM_ENUMERATION(name, sample, custom_ranges)          \
-    STATIC_HISTOGRAM_POINTER_BLOCK(name, Add(sample),                          \
-        base::CustomHistogram::FactoryGet(name, custom_ranges,                 \
-            base::HistogramBase::kUmaTargetedHistogramFlag))
-
-#endif  // BASE_METRICS_HISTOGRAM_MACROS_H_
diff --git a/base/metrics/histogram_macros_internal.h b/base/metrics/histogram_macros_internal.h
deleted file mode 100644
index ff3702b..0000000
--- a/base/metrics/histogram_macros_internal.h
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#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"
-#include "base/metrics/sparse_histogram.h"
-#include "base/time/time.h"
-
-// This is for macros and helpers internal to base/metrics. They should not be
-// used outside of this directory. For writing to UMA histograms, see
-// histogram_macros.h.
-
-namespace base {
-namespace internal {
-
-// Helper traits for deducing the boundary value for enums.
-template <typename Enum, typename SFINAE = void>
-struct EnumSizeTraits {
-  static constexpr Enum Count() {
-    static_assert(
-        sizeof(Enum) == 0,
-        "enumerator must define kMaxValue enumerator to use this macro!");
-    return Enum();
-  }
-};
-
-// Since the UMA histogram macros expect a value one larger than the max defined
-// enumerator value, add one.
-template <typename Enum>
-struct EnumSizeTraits<
-    Enum,
-    std::enable_if_t<std::is_enum<decltype(Enum::kMaxValue)>::value>> {
-  static constexpr Enum Count() {
-    return static_cast<Enum>(
-        static_cast<std::underlying_type_t<Enum>>(Enum::kMaxValue) + 1);
-  }
-};
-
-}  // namespace internal
-}  // namespace base
-
-// TODO(rkaplow): Improve commenting of these methods.
-//------------------------------------------------------------------------------
-// Histograms are often put in areas where they are called many many times, and
-// performance is critical.  As a result, they are designed to have a very low
-// recurring cost of executing (adding additional samples). Toward that end,
-// the macros declare a static pointer to the histogram in question, and only
-// take a "slow path" to construct (or find) the histogram on the first run
-// through the macro. We leak the histograms at shutdown time so that we don't
-// have to validate using the pointers at any time during the running of the
-// process.
-
-// In some cases (integration into 3rd party code), it's useful to separate the
-// definition of |atomic_histogram_pointer| from its use. To achieve this we
-// define HISTOGRAM_POINTER_USE, which uses an |atomic_histogram_pointer|, and
-// STATIC_HISTOGRAM_POINTER_BLOCK, which defines an |atomic_histogram_pointer|
-// and forwards to HISTOGRAM_POINTER_USE.
-#define HISTOGRAM_POINTER_USE(atomic_histogram_pointer,                        \
-                              constant_histogram_name,                         \
-                              histogram_add_method_invocation,                 \
-                              histogram_factory_get_invocation)                \
-  do {                                                                         \
-    /*                                                                         \
-     * Acquire_Load() ensures that we acquire visibility to the                \
-     * pointed-to data in the histogram.                                       \
-     */                                                                        \
-    base::HistogramBase* histogram_pointer(                                    \
-        reinterpret_cast<base::HistogramBase*>(                                \
-            base::subtle::Acquire_Load(atomic_histogram_pointer)));            \
-    if (!histogram_pointer) {                                                  \
-      /*                                                                       \
-       * This is the slow path, which will construct OR find the               \
-       * matching histogram.  histogram_factory_get_invocation includes        \
-       * locks on a global histogram name map and is completely thread         \
-       * safe.                                                                 \
-       */                                                                      \
-      histogram_pointer = histogram_factory_get_invocation;                    \
-                                                                               \
-      /*                                                                       \
-       * Use Release_Store to ensure that the histogram data is made           \
-       * available globally before we make the pointer visible. Several        \
-       * threads may perform this store, but the same value will be            \
-       * stored in all cases (for a given named/spec'ed histogram).            \
-       * We could do this without any barrier, since FactoryGet entered        \
-       * and exited a lock after construction, but this barrier makes          \
-       * things clear.                                                         \
-       */                                                                      \
-      base::subtle::Release_Store(                                             \
-          atomic_histogram_pointer,                                            \
-          reinterpret_cast<base::subtle::AtomicWord>(histogram_pointer));      \
-    }                                                                          \
-    if (DCHECK_IS_ON())                                                        \
-      histogram_pointer->CheckName(constant_histogram_name);                   \
-    histogram_pointer->histogram_add_method_invocation;                        \
-  } while (0)
-
-// This is a helper macro used by other macros and shouldn't be used directly.
-// Defines the static |atomic_histogram_pointer| and forwards to
-// HISTOGRAM_POINTER_USE.
-#define STATIC_HISTOGRAM_POINTER_BLOCK(constant_histogram_name,                \
-                                       histogram_add_method_invocation,        \
-                                       histogram_factory_get_invocation)       \
-  do {                                                                         \
-    /*                                                                         \
-     * The pointer's presence indicates that the initialization is complete.   \
-     * Initialization is idempotent, so it can safely be atomically repeated.  \
-     */                                                                        \
-    static base::subtle::AtomicWord atomic_histogram_pointer = 0;              \
-    HISTOGRAM_POINTER_USE(&atomic_histogram_pointer, constant_histogram_name,  \
-                          histogram_add_method_invocation,                     \
-                          histogram_factory_get_invocation);                   \
-  } while (0)
-
-// This is a helper macro used by other macros and shouldn't be used directly.
-#define INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG(name, sample, min, max,     \
-                                                   bucket_count, flag)         \
-    STATIC_HISTOGRAM_POINTER_BLOCK(                                            \
-        name, Add(sample),                                                     \
-        base::Histogram::FactoryGet(name, min, max, bucket_count, flag))
-
-// This is a helper macro used by other macros and shouldn't be used directly.
-// 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 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)
-
-// Helper for 'overloading' UMA_HISTOGRAM_ENUMERATION with a variable number of
-// arguments.
-#define INTERNAL_UMA_HISTOGRAM_ENUMERATION_GET_MACRO(_1, _2, NAME, ...) NAME
-
-#define INTERNAL_UMA_HISTOGRAM_ENUMERATION_DEDUCE_BOUNDARY(name, sample,       \
-                                                           flags)              \
-  INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG(                                    \
-      name, sample, base::internal::EnumSizeTraits<decltype(sample)>::Count(), \
-      flags)
-
-// Note: The value in |sample| must be strictly less than |enum_size|.
-#define INTERNAL_UMA_HISTOGRAM_ENUMERATION_SPECIFY_BOUNDARY(name, sample,     \
-                                                            enum_size, flags) \
-  INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, enum_size, flags)
-
-// 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 size isn't out of range of HistogramBase::Sample
-// - that the declared enum size is > 0
-//
-// TODO(dcheng): This should assert that the passed in types are actually enum
-// types.
-#define INTERNAL_HISTOGRAM_ENUMERATION_WITH_FLAG(name, sample, boundary, flag) \
-  do {                                                                         \
-    using decayed_sample = std::decay<decltype(sample)>::type;                 \
-    using decayed_boundary = std::decay<decltype(boundary)>::type;             \
-    static_assert(!std::is_enum<decayed_boundary>::value ||                    \
-                      std::is_enum<decayed_sample>::value,                     \
-                  "Unexpected: |boundary| is enum, but |sample| is not.");     \
-    static_assert(!std::is_enum<decayed_sample>::value ||                      \
-                      !std::is_enum<decayed_boundary>::value ||                \
-                      std::is_same<decayed_sample, decayed_boundary>::value,   \
-                  "|sample| and |boundary| shouldn't be of different enums");  \
-    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.
-// This is necessary to expand __COUNTER__ to an actual value.
-#define INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_EXPANDER(name, is_long, key)       \
-  INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_UNIQUE(name, is_long, key)
-
-// This is a helper macro used by other macros and shouldn't be used directly.
-#define INTERNAL_SCOPED_UMA_HISTOGRAM_TIMER_UNIQUE(name, is_long, key)         \
-  class ScopedHistogramTimer##key {                                            \
-   public:                                                                     \
-    ScopedHistogramTimer##key() : constructed_(base::TimeTicks::Now()) {}      \
-    ~ScopedHistogramTimer##key() {                                             \
-      base::TimeDelta elapsed = base::TimeTicks::Now() - constructed_;         \
-      if (is_long) {                                                           \
-        UMA_HISTOGRAM_LONG_TIMES_100(name, elapsed);                           \
-      } else {                                                                 \
-        UMA_HISTOGRAM_TIMES(name, elapsed);                                    \
-      }                                                                        \
-    }                                                                          \
-   private:                                                                    \
-    base::TimeTicks constructed_;                                              \
-  } scoped_histogram_timer_##key
-
-#endif  // BASE_METRICS_HISTOGRAM_MACROS_INTERNAL_H_
diff --git a/base/metrics/histogram_macros_local.h b/base/metrics/histogram_macros_local.h
deleted file mode 100644
index c4d333b..0000000
--- a/base/metrics/histogram_macros_local.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_MACROS_LOCAL_H_
-#define BASE_METRICS_HISTOGRAM_MACROS_LOCAL_H_
-
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_macros_internal.h"
-#include "base/time/time.h"
-
-// TODO(rkaplow): Migrate all LOCAL_* usage within Chromium to include this
-// file instead of the histogram_macros.h file.
-
-//------------------------------------------------------------------------------
-// Enumeration histograms.
-//
-// For usage details, see the equivalents in histogram_macros.h.
-
-#define LOCAL_HISTOGRAM_ENUMERATION(name, ...)                          \
-  CR_EXPAND_ARG(INTERNAL_UMA_HISTOGRAM_ENUMERATION_GET_MACRO(           \
-      __VA_ARGS__, INTERNAL_UMA_HISTOGRAM_ENUMERATION_SPECIFY_BOUNDARY, \
-      INTERNAL_UMA_HISTOGRAM_ENUMERATION_DEDUCE_BOUNDARY)(              \
-      name, __VA_ARGS__, base::HistogramBase::kNoFlags))
-
-#define LOCAL_HISTOGRAM_BOOLEAN(name, sample)                                  \
-    STATIC_HISTOGRAM_POINTER_BLOCK(name, AddBoolean(sample),                   \
-        base::BooleanHistogram::FactoryGet(name, base::Histogram::kNoFlags))
-
-//------------------------------------------------------------------------------
-// Percentage histograms.
-//
-// For usage details, see the equivalents in histogram_macros.h
-
-#define LOCAL_HISTOGRAM_PERCENTAGE(name, under_one_hundred)                    \
-    LOCAL_HISTOGRAM_ENUMERATION(name, under_one_hundred, 101)
-
-//------------------------------------------------------------------------------
-// Count histograms. These are used for collecting numeric data. Note that we
-// have macros for more specialized use cases below (memory, time, percentages).
-// For usage details, see the equivalents in histogram_macros.h.
-
-#define LOCAL_HISTOGRAM_COUNTS_100(name, sample)                               \
-    LOCAL_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 100, 50)
-
-#define LOCAL_HISTOGRAM_COUNTS_10000(name, sample)                             \
-    LOCAL_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 10000, 50)
-
-#define LOCAL_HISTOGRAM_COUNTS_1000000(name, sample)                           \
-    LOCAL_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000000, 50)
-
-#define LOCAL_HISTOGRAM_CUSTOM_COUNTS(name, sample, min, max, bucket_count)    \
-    INTERNAL_HISTOGRAM_CUSTOM_COUNTS_WITH_FLAG(                                \
-        name, sample, min, max, bucket_count, base::HistogramBase::kNoFlags)
-
-//------------------------------------------------------------------------------
-// Timing histograms. These are used for collecting timing data (generally
-// latencies).
-//
-// For usage details, see the equivalents in histogram_macros.h.
-
-#define LOCAL_HISTOGRAM_TIMES(name, sample) LOCAL_HISTOGRAM_CUSTOM_TIMES(      \
-    name, sample, base::TimeDelta::FromMilliseconds(1),                        \
-    base::TimeDelta::FromSeconds(10), 50)
-
-#define LOCAL_HISTOGRAM_CUSTOM_TIMES(name, sample, min, max, bucket_count) \
-  STATIC_HISTOGRAM_POINTER_BLOCK(                                          \
-      name, AddTimeMillisecondsGranularity(sample),                        \
-      base::Histogram::FactoryTimeGet(name, min, max, bucket_count,        \
-                                      base::HistogramBase::kNoFlags))
-
-//------------------------------------------------------------------------------
-// Memory histograms.
-//
-// For usage details, see the equivalents in histogram_macros.h.
-
-#define LOCAL_HISTOGRAM_MEMORY_KB(name, sample) LOCAL_HISTOGRAM_CUSTOM_COUNTS( \
-    name, sample, 1000, 500000, 50)
-
-//------------------------------------------------------------------------------
-// Deprecated histograms. Not recommended for current use.
-
-// TODO(rkaplow): See if we can clean up this macro and usage.
-// Legacy non-explicit version. We suggest using LOCAL_HISTOGRAM_COUNTS_1000000
-// instead.
-#define LOCAL_HISTOGRAM_COUNTS(name, sample)                                   \
-    LOCAL_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, 1000000, 50)
-
-#endif  // BASE_METRICS_HISTOGRAM_MACROS_LOCAL_H_
diff --git a/base/metrics/histogram_samples.cc b/base/metrics/histogram_samples.cc
deleted file mode 100644
index 6830637..0000000
--- a/base/metrics/histogram_samples.cc
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/histogram_samples.h"
-
-#include <limits>
-
-#include "base/compiler_specific.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/numerics/safe_math.h"
-#include "base/pickle.h"
-
-namespace base {
-
-namespace {
-
-// A shorthand constant for the max value of size_t.
-constexpr size_t kSizeMax = std::numeric_limits<size_t>::max();
-
-// A constant stored in an AtomicSingleSample (as_atomic) to indicate that the
-// sample is "disabled" and no further accumulation should be done with it. The
-// value is chosen such that it will be MAX_UINT16 for both |bucket| & |count|,
-// and thus less likely to conflict with real use. Conflicts are explicitly
-// handled in the code but it's worth making them as unlikely as possible.
-constexpr int32_t kDisabledSingleSample = -1;
-
-class SampleCountPickleIterator : public SampleCountIterator {
- public:
-  explicit SampleCountPickleIterator(PickleIterator* iter);
-
-  bool Done() const override;
-  void Next() override;
-  void Get(HistogramBase::Sample* min,
-           int64_t* max,
-           HistogramBase::Count* count) const override;
-
- private:
-  PickleIterator* const iter_;
-
-  HistogramBase::Sample min_;
-  int64_t max_;
-  HistogramBase::Count count_;
-  bool is_done_;
-};
-
-SampleCountPickleIterator::SampleCountPickleIterator(PickleIterator* iter)
-    : iter_(iter),
-      is_done_(false) {
-  Next();
-}
-
-bool SampleCountPickleIterator::Done() const {
-  return is_done_;
-}
-
-void SampleCountPickleIterator::Next() {
-  DCHECK(!Done());
-  if (!iter_->ReadInt(&min_) || !iter_->ReadInt64(&max_) ||
-      !iter_->ReadInt(&count_)) {
-    is_done_ = true;
-  }
-}
-
-void SampleCountPickleIterator::Get(HistogramBase::Sample* min,
-                                    int64_t* max,
-                                    HistogramBase::Count* count) const {
-  DCHECK(!Done());
-  *min = min_;
-  *max = max_;
-  *count = count_;
-}
-
-}  // namespace
-
-static_assert(sizeof(HistogramSamples::AtomicSingleSample) ==
-                  sizeof(subtle::Atomic32),
-              "AtomicSingleSample isn't 32 bits");
-
-HistogramSamples::SingleSample HistogramSamples::AtomicSingleSample::Load()
-    const {
-  AtomicSingleSample single_sample = subtle::Acquire_Load(&as_atomic);
-
-  // If the sample was extracted/disabled, it's still zero to the outside.
-  if (single_sample.as_atomic == kDisabledSingleSample)
-    single_sample.as_atomic = 0;
-
-  return single_sample.as_parts;
-}
-
-HistogramSamples::SingleSample HistogramSamples::AtomicSingleSample::Extract(
-    bool disable) {
-  AtomicSingleSample single_sample = subtle::NoBarrier_AtomicExchange(
-      &as_atomic, disable ? kDisabledSingleSample : 0);
-  if (single_sample.as_atomic == kDisabledSingleSample)
-    single_sample.as_atomic = 0;
-  return single_sample.as_parts;
-}
-
-bool HistogramSamples::AtomicSingleSample::Accumulate(
-    size_t bucket,
-    HistogramBase::Count count) {
-  if (count == 0)
-    return true;
-
-  // Convert the parameters to 16-bit variables because it's all 16-bit below.
-  // To support decrements/subtractions, divide the |count| into sign/value and
-  // do the proper operation below. The alternative is to change the single-
-  // sample's count to be a signed integer (int16_t) and just add an int16_t
-  // |count16| but that is somewhat wasteful given that the single-sample is
-  // never expected to have a count less than zero.
-  if (count < -std::numeric_limits<uint16_t>::max() ||
-      count > std::numeric_limits<uint16_t>::max() ||
-      bucket > std::numeric_limits<uint16_t>::max()) {
-    return false;
-  }
-  bool count_is_negative = count < 0;
-  uint16_t count16 = static_cast<uint16_t>(count_is_negative ? -count : count);
-  uint16_t bucket16 = static_cast<uint16_t>(bucket);
-
-  // A local, unshared copy of the single-sample is necessary so the parts
-  // can be manipulated without worrying about atomicity.
-  AtomicSingleSample single_sample;
-
-  bool sample_updated;
-  do {
-    subtle::Atomic32 original = subtle::Acquire_Load(&as_atomic);
-    if (original == kDisabledSingleSample)
-      return false;
-    single_sample.as_atomic = original;
-    if (single_sample.as_atomic != 0) {
-      // Only the same bucket (parameter and stored) can be counted multiple
-      // times.
-      if (single_sample.as_parts.bucket != bucket16)
-        return false;
-    } else {
-      // The |single_ sample| was zero so becomes the |bucket| parameter, the
-      // contents of which were checked above to fit in 16 bits.
-      single_sample.as_parts.bucket = bucket16;
-    }
-
-    // Update count, making sure that it doesn't overflow.
-    CheckedNumeric<uint16_t> new_count(single_sample.as_parts.count);
-    if (count_is_negative)
-      new_count -= count16;
-    else
-      new_count += count16;
-    if (!new_count.AssignIfValid(&single_sample.as_parts.count))
-      return false;
-
-    // Don't let this become equivalent to the "disabled" value.
-    if (single_sample.as_atomic == kDisabledSingleSample)
-      return false;
-
-    // Store the updated single-sample back into memory. |existing| is what
-    // was in that memory location at the time of the call; if it doesn't
-    // match |original| then the swap didn't happen so loop again.
-    subtle::Atomic32 existing = subtle::Release_CompareAndSwap(
-        &as_atomic, original, single_sample.as_atomic);
-    sample_updated = (existing == original);
-  } while (!sample_updated);
-
-  return true;
-}
-
-bool HistogramSamples::AtomicSingleSample::IsDisabled() const {
-  return subtle::Acquire_Load(&as_atomic) == kDisabledSingleSample;
-}
-
-HistogramSamples::LocalMetadata::LocalMetadata() {
-  // This is the same way it's done for persistent metadata since no ctor
-  // is called for the data members in that case.
-  memset(this, 0, sizeof(*this));
-}
-
-HistogramSamples::HistogramSamples(uint64_t id, Metadata* meta)
-    : meta_(meta) {
-  DCHECK(meta_->id == 0 || meta_->id == id);
-
-  // It's possible that |meta| is contained in initialized, read-only memory
-  // so it's essential that no write be done in that case.
-  if (!meta_->id)
-    meta_->id = id;
-}
-
-// This mustn't do anything with |meta_|. It was passed to the ctor and may
-// be invalid by the time this dtor gets called.
-HistogramSamples::~HistogramSamples() = default;
-
-void HistogramSamples::Add(const HistogramSamples& other) {
-  IncreaseSumAndCount(other.sum(), other.redundant_count());
-  std::unique_ptr<SampleCountIterator> it = other.Iterator();
-  bool success = AddSubtractImpl(it.get(), ADD);
-  DCHECK(success);
-}
-
-bool HistogramSamples::AddFromPickle(PickleIterator* iter) {
-  int64_t sum;
-  HistogramBase::Count redundant_count;
-
-  if (!iter->ReadInt64(&sum) || !iter->ReadInt(&redundant_count))
-    return false;
-
-  IncreaseSumAndCount(sum, redundant_count);
-
-  SampleCountPickleIterator pickle_iter(iter);
-  return AddSubtractImpl(&pickle_iter, ADD);
-}
-
-void HistogramSamples::Subtract(const HistogramSamples& other) {
-  IncreaseSumAndCount(-other.sum(), -other.redundant_count());
-  std::unique_ptr<SampleCountIterator> it = other.Iterator();
-  bool success = AddSubtractImpl(it.get(), SUBTRACT);
-  DCHECK(success);
-}
-
-void HistogramSamples::Serialize(Pickle* pickle) const {
-  pickle->WriteInt64(sum());
-  pickle->WriteInt(redundant_count());
-
-  HistogramBase::Sample min;
-  int64_t max;
-  HistogramBase::Count count;
-  for (std::unique_ptr<SampleCountIterator> it = Iterator(); !it->Done();
-       it->Next()) {
-    it->Get(&min, &max, &count);
-    pickle->WriteInt(min);
-    pickle->WriteInt64(max);
-    pickle->WriteInt(count);
-  }
-}
-
-bool HistogramSamples::AccumulateSingleSample(HistogramBase::Sample value,
-                                              HistogramBase::Count count,
-                                              size_t bucket) {
-  if (single_sample().Accumulate(bucket, count)) {
-    // Success. Update the (separate) sum and redundant-count.
-    IncreaseSumAndCount(strict_cast<int64_t>(value) * count, count);
-    return true;
-  }
-  return false;
-}
-
-void HistogramSamples::IncreaseSumAndCount(int64_t sum,
-                                           HistogramBase::Count count) {
-#ifdef ARCH_CPU_64_BITS
-  subtle::NoBarrier_AtomicIncrement(&meta_->sum, sum);
-#else
-  meta_->sum += sum;
-#endif
-  subtle::NoBarrier_AtomicIncrement(&meta_->redundant_count, count);
-}
-
-void HistogramSamples::RecordNegativeSample(NegativeSampleReason reason,
-                                            HistogramBase::Count increment) {
-  UMA_HISTOGRAM_ENUMERATION("UMA.NegativeSamples.Reason", reason,
-                            MAX_NEGATIVE_SAMPLE_REASONS);
-  UMA_HISTOGRAM_CUSTOM_COUNTS("UMA.NegativeSamples.Increment", increment, 1,
-                              1 << 30, 100);
-  UmaHistogramSparse("UMA.NegativeSamples.Histogram",
-                     static_cast<int32_t>(id()));
-}
-
-SampleCountIterator::~SampleCountIterator() = default;
-
-bool SampleCountIterator::GetBucketIndex(size_t* index) const {
-  DCHECK(!Done());
-  return false;
-}
-
-SingleSampleIterator::SingleSampleIterator(HistogramBase::Sample min,
-                                           int64_t max,
-                                           HistogramBase::Count count)
-    : SingleSampleIterator(min, max, count, kSizeMax) {}
-
-SingleSampleIterator::SingleSampleIterator(HistogramBase::Sample min,
-                                           int64_t max,
-                                           HistogramBase::Count count,
-                                           size_t bucket_index)
-    : min_(min), max_(max), bucket_index_(bucket_index), count_(count) {}
-
-SingleSampleIterator::~SingleSampleIterator() = default;
-
-bool SingleSampleIterator::Done() const {
-  return count_ == 0;
-}
-
-void SingleSampleIterator::Next() {
-  DCHECK(!Done());
-  count_ = 0;
-}
-
-void SingleSampleIterator::Get(HistogramBase::Sample* min,
-                               int64_t* max,
-                               HistogramBase::Count* count) const {
-  DCHECK(!Done());
-  if (min != nullptr)
-    *min = min_;
-  if (max != nullptr)
-    *max = max_;
-  if (count != nullptr)
-    *count = count_;
-}
-
-bool SingleSampleIterator::GetBucketIndex(size_t* index) const {
-  DCHECK(!Done());
-  if (bucket_index_ == kSizeMax)
-    return false;
-  *index = bucket_index_;
-  return true;
-}
-
-}  // namespace base
diff --git a/base/metrics/histogram_samples.h b/base/metrics/histogram_samples.h
deleted file mode 100644
index 059fd3c..0000000
--- a/base/metrics/histogram_samples.h
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_SAMPLES_H_
-#define BASE_METRICS_HISTOGRAM_SAMPLES_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <limits>
-#include <memory>
-
-#include "base/atomicops.h"
-#include "base/macros.h"
-#include "base/metrics/histogram_base.h"
-
-namespace base {
-
-class Pickle;
-class PickleIterator;
-class SampleCountIterator;
-
-// HistogramSamples is a container storing all samples of a histogram. All
-// elements must be of a fixed width to ensure 32/64-bit interoperability.
-// If this structure changes, bump the version number for kTypeIdHistogram
-// in persistent_histogram_allocator.cc.
-//
-// Note that though these samples are individually consistent (through the use
-// of atomic operations on the counts), there is only "eventual consistency"
-// overall when multiple threads are accessing this data. That means that the
-// sum, redundant-count, etc. could be momentarily out-of-sync with the stored
-// counts but will settle to a consistent "steady state" once all threads have
-// exited this code.
-class BASE_EXPORT HistogramSamples {
- public:
-  // A single bucket and count. To fit within a single atomic on 32-bit build
-  // architectures, both |bucket| and |count| are limited in size to 16 bits.
-  // This limits the functionality somewhat but if an entry can't fit then
-  // the full array of samples can be allocated and used.
-  struct SingleSample {
-    uint16_t bucket;
-    uint16_t count;
-  };
-
-  // A structure for managing an atomic single sample. Because this is generally
-  // used in association with other atomic values, the defined methods use
-  // acquire/release operations to guarantee ordering with outside values.
-  union BASE_EXPORT AtomicSingleSample {
-    AtomicSingleSample() : as_atomic(0) {}
-    AtomicSingleSample(subtle::Atomic32 rhs) : as_atomic(rhs) {}
-
-    // Returns the single sample in an atomic manner. This in an "acquire"
-    // load. The returned sample isn't shared and thus its fields can be safely
-    // accessed.
-    SingleSample Load() const;
-
-    // Extracts the single sample in an atomic manner. If |disable| is true
-    // then this object will be set so it will never accumulate another value.
-    // This is "no barrier" so doesn't enforce ordering with other atomic ops.
-    SingleSample Extract(bool disable);
-
-    // Adds a given count to the held bucket. If not possible, it returns false
-    // and leaves the parts unchanged. Once extracted/disabled, this always
-    // returns false. This in an "acquire/release" operation.
-    bool Accumulate(size_t bucket, HistogramBase::Count count);
-
-    // Returns if the sample has been "disabled" (via Extract) and thus not
-    // allowed to accept further accumulation.
-    bool IsDisabled() const;
-
-   private:
-    // union field: The actual sample bucket and count.
-    SingleSample as_parts;
-
-    // union field: The sample as an atomic value. Atomic64 would provide
-    // more flexibility but isn't available on all builds. This can hold a
-    // special, internal "disabled" value indicating that it must not accept
-    // further accumulation.
-    subtle::Atomic32 as_atomic;
-  };
-
-  // A structure of information about the data, common to all sample containers.
-  // Because of how this is used in persistent memory, it must be a POD object
-  // that makes sense when initialized to all zeros.
-  struct Metadata {
-    // Expected size for 32/64-bit check.
-    static constexpr size_t kExpectedInstanceSize = 24;
-
-    // Initialized when the sample-set is first created with a value provided
-    // by the caller. It is generally used to identify the sample-set across
-    // threads and processes, though not necessarily uniquely as it is possible
-    // to have multiple sample-sets representing subsets of the data.
-    uint64_t id;
-
-    // The sum of all the entries, effectivly the sum(sample * count) for
-    // all samples. Despite being atomic, no guarantees are made on the
-    // accuracy of this value; there may be races during histogram
-    // accumulation and snapshotting that we choose to accept. It should
-    // be treated as approximate.
-#ifdef ARCH_CPU_64_BITS
-    subtle::Atomic64 sum;
-#else
-    // 32-bit systems don't have atomic 64-bit operations. Use a basic type
-    // and don't worry about "shearing".
-    int64_t sum;
-#endif
-
-    // A "redundant" count helps identify memory corruption. It redundantly
-    // stores the total number of samples accumulated in the histogram. We
-    // can compare this count to the sum of the counts (TotalCount() function),
-    // and detect problems. Note, depending on the implementation of different
-    // histogram types, there might be races during histogram accumulation
-    // and snapshotting that we choose to accept. In this case, the tallies
-    // might mismatch even when no memory corruption has happened.
-    HistogramBase::AtomicCount redundant_count;
-
-    // A single histogram value and associated count. This allows histograms
-    // that typically report only a single value to not require full storage
-    // to be allocated.
-    AtomicSingleSample single_sample;  // 32 bits
-  };
-
-  // Because structures held in persistent memory must be POD, there can be no
-  // default constructor to clear the fields. This derived class exists just
-  // to clear them when being allocated on the heap.
-  struct BASE_EXPORT LocalMetadata : Metadata {
-    LocalMetadata();
-  };
-
-  HistogramSamples(uint64_t id, Metadata* meta);
-  virtual ~HistogramSamples();
-
-  virtual void Accumulate(HistogramBase::Sample value,
-                          HistogramBase::Count count) = 0;
-  virtual HistogramBase::Count GetCount(HistogramBase::Sample value) const = 0;
-  virtual HistogramBase::Count TotalCount() const = 0;
-
-  virtual void Add(const HistogramSamples& other);
-
-  // Add from serialized samples.
-  virtual bool AddFromPickle(PickleIterator* iter);
-
-  virtual void Subtract(const HistogramSamples& other);
-
-  virtual std::unique_ptr<SampleCountIterator> Iterator() const = 0;
-  virtual void Serialize(Pickle* pickle) const;
-
-  // Accessor fuctions.
-  uint64_t id() const { return meta_->id; }
-  int64_t sum() const {
-#ifdef ARCH_CPU_64_BITS
-    return subtle::NoBarrier_Load(&meta_->sum);
-#else
-    return meta_->sum;
-#endif
-  }
-  HistogramBase::Count redundant_count() const {
-    return subtle::NoBarrier_Load(&meta_->redundant_count);
-  }
-
-  // Temporarily visible for crash debugging. Should be protected.
-  // TODO(bcwhite): Move this back where it belongs.
-  // https://bugs.chromium.org/p/chromium/issues/detail?id=836875
-  Metadata* meta() { return meta_; }
-
- protected:
-  enum NegativeSampleReason {
-    SAMPLES_HAVE_LOGGED_BUT_NOT_SAMPLE,
-    SAMPLES_SAMPLE_LESS_THAN_LOGGED,
-    SAMPLES_ADDED_NEGATIVE_COUNT,
-    SAMPLES_ADD_WENT_NEGATIVE,
-    SAMPLES_ADD_OVERFLOW,
-    SAMPLES_ACCUMULATE_NEGATIVE_COUNT,
-    SAMPLES_ACCUMULATE_WENT_NEGATIVE,
-    DEPRECATED_SAMPLES_ACCUMULATE_OVERFLOW,
-    SAMPLES_ACCUMULATE_OVERFLOW,
-    MAX_NEGATIVE_SAMPLE_REASONS
-  };
-
-  // Based on |op| type, add or subtract sample counts data from the iterator.
-  enum Operator { ADD, SUBTRACT };
-  virtual bool AddSubtractImpl(SampleCountIterator* iter, Operator op) = 0;
-
-  // Accumulates to the embedded single-sample field if possible. Returns true
-  // on success, false otherwise. Sum and redundant-count are also updated in
-  // the success case.
-  bool AccumulateSingleSample(HistogramBase::Sample value,
-                              HistogramBase::Count count,
-                              size_t bucket);
-
-  // Atomically adjust the sum and redundant-count.
-  void IncreaseSumAndCount(int64_t sum, HistogramBase::Count count);
-
-  // Record a negative-sample observation and the reason why.
-  void RecordNegativeSample(NegativeSampleReason reason,
-                            HistogramBase::Count increment);
-
-  AtomicSingleSample& single_sample() { return meta_->single_sample; }
-  const AtomicSingleSample& single_sample() const {
-    return meta_->single_sample;
-  }
-
- private:
-  // Depending on derived class meta values can come from local stoarge or
-  // external storage in which case HistogramSamples class cannot take ownership
-  // of Metadata*.
-  Metadata* meta_;
-
-  DISALLOW_COPY_AND_ASSIGN(HistogramSamples);
-};
-
-class BASE_EXPORT SampleCountIterator {
- public:
-  virtual ~SampleCountIterator();
-
-  virtual bool Done() const = 0;
-  virtual void Next() = 0;
-
-  // Get the sample and count at current position.
-  // |min| |max| and |count| can be NULL if the value is not of interest.
-  // Note: |max| is int64_t because histograms support logged values in the
-  // full int32_t range and bucket max is exclusive, so it needs to support
-  // values up to MAXINT32+1.
-  // Requires: !Done();
-  virtual void Get(HistogramBase::Sample* min,
-                   int64_t* max,
-                   HistogramBase::Count* count) const = 0;
-  static_assert(std::numeric_limits<HistogramBase::Sample>::max() <
-                    std::numeric_limits<int64_t>::max(),
-                "Get() |max| must be able to hold Histogram::Sample max + 1");
-
-  // Get the index of current histogram bucket.
-  // For histograms that don't use predefined buckets, it returns false.
-  // Requires: !Done();
-  virtual bool GetBucketIndex(size_t* index) const;
-};
-
-class BASE_EXPORT SingleSampleIterator : public SampleCountIterator {
- public:
-  SingleSampleIterator(HistogramBase::Sample min,
-                       int64_t max,
-                       HistogramBase::Count count);
-  SingleSampleIterator(HistogramBase::Sample min,
-                       int64_t max,
-                       HistogramBase::Count count,
-                       size_t bucket_index);
-  ~SingleSampleIterator() override;
-
-  // SampleCountIterator:
-  bool Done() const override;
-  void Next() override;
-  void Get(HistogramBase::Sample* min,
-           int64_t* max,
-           HistogramBase::Count* count) const override;
-
-  // SampleVector uses predefined buckets so iterator can return bucket index.
-  bool GetBucketIndex(size_t* index) const override;
-
- private:
-  // Information about the single value to return.
-  const HistogramBase::Sample min_;
-  const int64_t max_;
-  const size_t bucket_index_;
-  HistogramBase::Count count_;
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_HISTOGRAM_SAMPLES_H_
diff --git a/base/metrics/histogram_snapshot_manager.cc b/base/metrics/histogram_snapshot_manager.cc
deleted file mode 100644
index c1b804e..0000000
--- a/base/metrics/histogram_snapshot_manager.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/histogram_snapshot_manager.h"
-
-#include <memory>
-
-#include "base/debug/alias.h"
-#include "base/metrics/histogram_flattener.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/stl_util.h"
-
-namespace base {
-
-namespace {
-
-// A simple object to set an "active" flag and clear it upon destruction. It is
-// an error if the flag is already set.
-class MakeActive {
- public:
-  MakeActive(std::atomic<bool>* is_active) : is_active_(is_active) {
-    bool was_active = is_active_->exchange(true, std::memory_order_relaxed);
-    CHECK(!was_active);
-  }
-  ~MakeActive() { is_active_->store(false, std::memory_order_relaxed); }
-
- private:
-  std::atomic<bool>* is_active_;
-
-  DISALLOW_COPY_AND_ASSIGN(MakeActive);
-};
-
-}  // namespace
-
-HistogramSnapshotManager::HistogramSnapshotManager(
-    HistogramFlattener* histogram_flattener)
-    : histogram_flattener_(histogram_flattener) {
-  DCHECK(histogram_flattener_);
-  is_active_.store(false, std::memory_order_relaxed);
-}
-
-HistogramSnapshotManager::~HistogramSnapshotManager() = default;
-
-void HistogramSnapshotManager::PrepareDeltas(
-    const std::vector<HistogramBase*>& histograms,
-    HistogramBase::Flags flags_to_set,
-    HistogramBase::Flags required_flags) {
-  for (HistogramBase* const histogram : histograms) {
-    histogram->SetFlags(flags_to_set);
-    if ((histogram->flags() & required_flags) == required_flags)
-      PrepareDelta(histogram);
-  }
-}
-
-void HistogramSnapshotManager::PrepareDelta(HistogramBase* histogram) {
-  histogram->ValidateHistogramContents();
-  PrepareSamples(histogram, histogram->SnapshotDelta());
-}
-
-void HistogramSnapshotManager::PrepareFinalDelta(
-    const HistogramBase* histogram) {
-  histogram->ValidateHistogramContents();
-  PrepareSamples(histogram, histogram->SnapshotFinalDelta());
-}
-
-void HistogramSnapshotManager::PrepareSamples(
-    const HistogramBase* histogram,
-    std::unique_ptr<HistogramSamples> samples) {
-  DCHECK(histogram_flattener_);
-
-  // Ensure that there is no concurrent access going on while accessing the
-  // set of known histograms. The flag will be reset when this object goes
-  // out of scope.
-  MakeActive make_active(&is_active_);
-
-  // Get information known about this histogram. If it did not previously
-  // exist, one will be created and initialized.
-  SampleInfo* sample_info = &known_histograms_[histogram->name_hash()];
-
-  // Crash if we detect that our histograms have been overwritten.  This may be
-  // a fair distance from the memory smasher, but we hope to correlate these
-  // crashes with other events, such as plugins, or usage patterns, etc.
-  uint32_t corruption = histogram->FindCorruption(*samples);
-  if (HistogramBase::BUCKET_ORDER_ERROR & corruption) {
-    // Extract fields useful during debug.
-    const BucketRanges* ranges =
-        static_cast<const Histogram*>(histogram)->bucket_ranges();
-    uint32_t ranges_checksum = ranges->checksum();
-    uint32_t ranges_calc_checksum = ranges->CalculateChecksum();
-    int32_t flags = histogram->flags();
-    // The checksum should have caught this, so crash separately if it didn't.
-    CHECK_NE(0U, HistogramBase::RANGE_CHECKSUM_ERROR & corruption);
-    CHECK(false);  // Crash for the bucket order corruption.
-    // Ensure that compiler keeps around pointers to |histogram| and its
-    // internal |bucket_ranges_| for any minidumps.
-    base::debug::Alias(&ranges_checksum);
-    base::debug::Alias(&ranges_calc_checksum);
-    base::debug::Alias(&flags);
-  }
-  // Checksum corruption might not have caused order corruption.
-  CHECK_EQ(0U, HistogramBase::RANGE_CHECKSUM_ERROR & corruption);
-
-  // Note, at this point corruption can only be COUNT_HIGH_ERROR or
-  // COUNT_LOW_ERROR and they never arise together, so we don't need to extract
-  // bits from corruption.
-  if (corruption) {
-    DLOG(ERROR) << "Histogram: \"" << histogram->histogram_name()
-                << "\" has data corruption: " << corruption;
-    // Don't record corrupt data to metrics services.
-    const uint32_t old_corruption = sample_info->inconsistencies;
-    if (old_corruption == (corruption | old_corruption))
-      return;  // We've already seen this corruption for this histogram.
-    sample_info->inconsistencies |= corruption;
-    return;
-  }
-
-  if (samples->TotalCount() > 0)
-    histogram_flattener_->RecordDelta(*histogram, *samples);
-}
-
-}  // namespace base
diff --git a/base/metrics/histogram_snapshot_manager.h b/base/metrics/histogram_snapshot_manager.h
deleted file mode 100644
index cf7c149..0000000
--- a/base/metrics/histogram_snapshot_manager.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_
-#define BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_
-
-#include <stdint.h>
-
-#include <atomic>
-#include <map>
-#include <string>
-#include <vector>
-
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/metrics/histogram_base.h"
-
-namespace base {
-
-class HistogramSamples;
-class HistogramFlattener;
-
-// HistogramSnapshotManager handles the logistics of gathering up available
-// histograms for recording either to disk or for transmission (such as from
-// renderer to browser, or from browser to UMA upload). Since histograms can sit
-// in memory for an extended period of time, and are vulnerable to memory
-// corruption, this class also validates as much redundancy as it can before
-// calling for the marginal change (a.k.a., delta) in a histogram to be
-// recorded.
-class BASE_EXPORT HistogramSnapshotManager final {
- public:
-  explicit HistogramSnapshotManager(HistogramFlattener* histogram_flattener);
-  ~HistogramSnapshotManager();
-
-  // Snapshot all histograms, and ask |histogram_flattener_| to record the
-  // delta. |flags_to_set| is used to set flags for each histogram.
-  // |required_flags| is used to select histograms to be recorded.
-  // Only histograms that have all the flags specified by the argument will be
-  // chosen. If all histograms should be recorded, set it to
-  // |Histogram::kNoFlags|.
-  void PrepareDeltas(const std::vector<HistogramBase*>& histograms,
-                     HistogramBase::Flags flags_to_set,
-                     HistogramBase::Flags required_flags);
-
-  // When the collection is not so simple as can be done using a single
-  // iterator, the steps can be performed separately. Call PerpareDelta()
-  // as many times as necessary. PrepareFinalDelta() works like PrepareDelta()
-  // except that it does not update the previous logged values and can thus
-  // be used with read-only files.
-  void PrepareDelta(HistogramBase* histogram);
-  void PrepareFinalDelta(const HistogramBase* histogram);
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(HistogramSnapshotManagerTest, CheckMerge);
-
-  // During a snapshot, samples are acquired and aggregated. This structure
-  // contains all the information for a given histogram that persists between
-  // collections.
-  struct SampleInfo {
-    // The set of inconsistencies (flags) already seen for the histogram.
-    // See HistogramBase::Inconsistency for values.
-    uint32_t inconsistencies = 0;
-  };
-
-  // Capture and hold samples from a histogram. This does all the heavy
-  // lifting for PrepareDelta() and PrepareAbsolute().
-  void PrepareSamples(const HistogramBase* histogram,
-                      std::unique_ptr<HistogramSamples> samples);
-
-  // |histogram_flattener_| handles the logistics of recording the histogram
-  // deltas.
-  HistogramFlattener* const histogram_flattener_;  // Weak.
-
-  // For histograms, track what has been previously seen, indexed
-  // by the hash of the histogram name.
-  std::map<uint64_t, SampleInfo> known_histograms_;
-
-  // A flag indicating if a thread is currently doing an operation. This is
-  // used to check against concurrent access which is not supported. A Thread-
-  // Checker is not sufficient because it may be guarded by at outside lock
-  // (as is the case with cronet).
-  std::atomic<bool> is_active_;
-
-  DISALLOW_COPY_AND_ASSIGN(HistogramSnapshotManager);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_HISTOGRAM_SNAPSHOT_MANAGER_H_
diff --git a/base/metrics/metrics_hashes.cc b/base/metrics/metrics_hashes.cc
deleted file mode 100644
index 5672b06..0000000
--- a/base/metrics/metrics_hashes.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/metrics_hashes.h"
-
-#include "base/logging.h"
-#include "base/md5.h"
-#include "base/sys_byteorder.h"
-
-namespace base {
-
-namespace {
-
-// Converts the 8-byte prefix of an MD5 hash into a uint64_t value.
-inline uint64_t DigestToUInt64(const base::MD5Digest& digest) {
-  uint64_t value;
-  DCHECK_GE(sizeof(digest.a), sizeof(value));
-  memcpy(&value, digest.a, sizeof(value));
-  return base::NetToHost64(value);
-}
-
-}  // namespace
-
-uint64_t HashMetricName(base::StringPiece name) {
-  base::MD5Digest digest;
-  base::MD5Sum(name.data(), name.size(), &digest);
-  return DigestToUInt64(digest);
-}
-
-}  // namespace metrics
diff --git a/base/metrics/metrics_hashes.h b/base/metrics/metrics_hashes.h
deleted file mode 100644
index d05c4ba..0000000
--- a/base/metrics/metrics_hashes.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_METRICS_HASHES_H_
-#define BASE_METRICS_METRICS_HASHES_H_
-
-#include <stdint.h>
-
-#include "base/base_export.h"
-#include "base/strings/string_piece.h"
-
-namespace base {
-
-// Computes a uint64_t hash of a given string based on its MD5 hash. Suitable
-// for metric names.
-BASE_EXPORT uint64_t HashMetricName(base::StringPiece name);
-
-}  // namespace metrics
-
-#endif  // BASE_METRICS_METRICS_HASHES_H_
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
deleted file mode 100644
index bfbb44b..0000000
--- a/base/metrics/persistent_histogram_allocator.cc
+++ /dev/null
@@ -1,1024 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/persistent_histogram_allocator.h"
-
-#include <memory>
-
-#include "base/atomicops.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/important_file_writer.h"
-#include "base/files/memory_mapped_file.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/metrics_hashes.h"
-#include "base/metrics/persistent_sample_map.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/pickle.h"
-#include "base/process/process_handle.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-namespace {
-
-// Type identifiers used when storing in persistent memory so they can be
-// identified during extraction; the first 4 bytes of the SHA1 of the name
-// is used as a unique integer. A "version number" is added to the base
-// so that, if the structure of that object changes, stored older versions
-// will be safely ignored.
-enum : uint32_t {
-  kTypeIdRangesArray = 0xBCEA225A + 1,  // SHA1(RangesArray) v1
-  kTypeIdCountsArray = 0x53215530 + 1,  // SHA1(CountsArray) v1
-};
-
-// The current globally-active persistent allocator for all new histograms.
-// The object held here will obviously not be destructed at process exit
-// but that's best since PersistentMemoryAllocator objects (that underlie
-// GlobalHistogramAllocator objects) are explicitly forbidden from doing
-// anything essential at exit anyway due to the fact that they depend on data
-// managed elsewhere and which could be destructed first. An AtomicWord is
-// used instead of std::atomic because the latter can create global ctors
-// and dtors.
-subtle::AtomicWord g_histogram_allocator = 0;
-
-// Take an array of range boundaries and create a proper BucketRanges object
-// which is returned to the caller. A return of nullptr indicates that the
-// passed boundaries are invalid.
-std::unique_ptr<BucketRanges> CreateRangesFromData(
-    HistogramBase::Sample* ranges_data,
-    uint32_t ranges_checksum,
-    size_t count) {
-  // To avoid racy destruction at shutdown, the following may be leaked.
-  std::unique_ptr<BucketRanges> ranges(new BucketRanges(count));
-  DCHECK_EQ(count, ranges->size());
-  for (size_t i = 0; i < count; ++i) {
-    if (i > 0 && ranges_data[i] <= ranges_data[i - 1])
-      return nullptr;
-    ranges->set_range(i, ranges_data[i]);
-  }
-
-  ranges->ResetChecksum();
-  if (ranges->checksum() != ranges_checksum)
-    return nullptr;
-
-  return ranges;
-}
-
-// Calculate the number of bytes required to store all of a histogram's
-// "counts". This will return zero (0) if |bucket_count| is not valid.
-size_t CalculateRequiredCountsBytes(size_t bucket_count) {
-  // 2 because each "sample count" also requires a backup "logged count"
-  // used for calculating the delta during snapshot operations.
-  const size_t kBytesPerBucket = 2 * sizeof(HistogramBase::AtomicCount);
-
-  // If the |bucket_count| is such that it would overflow the return type,
-  // perhaps as the result of a malicious actor, then return zero to
-  // indicate the problem to the caller.
-  if (bucket_count > std::numeric_limits<size_t>::max() / kBytesPerBucket)
-    return 0;
-
-  return bucket_count * kBytesPerBucket;
-}
-
-}  // namespace
-
-const Feature kPersistentHistogramsFeature{
-  "PersistentHistograms", FEATURE_DISABLED_BY_DEFAULT
-};
-
-
-PersistentSparseHistogramDataManager::PersistentSparseHistogramDataManager(
-    PersistentMemoryAllocator* allocator)
-    : allocator_(allocator), record_iterator_(allocator) {}
-
-PersistentSparseHistogramDataManager::~PersistentSparseHistogramDataManager() =
-    default;
-
-PersistentSampleMapRecords*
-PersistentSparseHistogramDataManager::UseSampleMapRecords(uint64_t id,
-                                                          const void* user) {
-  base::AutoLock auto_lock(lock_);
-  return GetSampleMapRecordsWhileLocked(id)->Acquire(user);
-}
-
-PersistentSampleMapRecords*
-PersistentSparseHistogramDataManager::GetSampleMapRecordsWhileLocked(
-    uint64_t id) {
-  lock_.AssertAcquired();
-
-  auto found = sample_records_.find(id);
-  if (found != sample_records_.end())
-    return found->second.get();
-
-  std::unique_ptr<PersistentSampleMapRecords>& samples = sample_records_[id];
-  samples = std::make_unique<PersistentSampleMapRecords>(this, id);
-  return samples.get();
-}
-
-bool PersistentSparseHistogramDataManager::LoadRecords(
-    PersistentSampleMapRecords* sample_map_records) {
-  // DataManager must be locked in order to access the found_ field of any
-  // PersistentSampleMapRecords object.
-  base::AutoLock auto_lock(lock_);
-  bool found = false;
-
-  // If there are already "found" entries for the passed object, move them.
-  if (!sample_map_records->found_.empty()) {
-    sample_map_records->records_.reserve(sample_map_records->records_.size() +
-                                         sample_map_records->found_.size());
-    sample_map_records->records_.insert(sample_map_records->records_.end(),
-                                        sample_map_records->found_.begin(),
-                                        sample_map_records->found_.end());
-    sample_map_records->found_.clear();
-    found = true;
-  }
-
-  // Acquiring a lock is a semi-expensive operation so load some records with
-  // each call. More than this number may be loaded if it takes longer to
-  // find at least one matching record for the passed object.
-  const int kMinimumNumberToLoad = 10;
-  const uint64_t match_id = sample_map_records->sample_map_id_;
-
-  // Loop while no enty is found OR we haven't yet loaded the minimum number.
-  // This will continue reading even after a match is found.
-  for (int count = 0; !found || count < kMinimumNumberToLoad; ++count) {
-    // Get the next sample-record. The iterator will always resume from where
-    // it left off even if it previously had nothing further to return.
-    uint64_t found_id;
-    PersistentMemoryAllocator::Reference ref =
-        PersistentSampleMap::GetNextPersistentRecord(record_iterator_,
-                                                     &found_id);
-
-    // Stop immediately if there are none.
-    if (!ref)
-      break;
-
-    // The sample-record could be for any sparse histogram. Add the reference
-    // to the appropriate collection for later use.
-    if (found_id == match_id) {
-      sample_map_records->records_.push_back(ref);
-      found = true;
-    } else {
-      PersistentSampleMapRecords* samples =
-          GetSampleMapRecordsWhileLocked(found_id);
-      DCHECK(samples);
-      samples->found_.push_back(ref);
-    }
-  }
-
-  return found;
-}
-
-
-PersistentSampleMapRecords::PersistentSampleMapRecords(
-    PersistentSparseHistogramDataManager* data_manager,
-    uint64_t sample_map_id)
-    : data_manager_(data_manager), sample_map_id_(sample_map_id) {}
-
-PersistentSampleMapRecords::~PersistentSampleMapRecords() = default;
-
-PersistentSampleMapRecords* PersistentSampleMapRecords::Acquire(
-    const void* user) {
-  DCHECK(!user_);
-  user_ = user;
-  seen_ = 0;
-  return this;
-}
-
-void PersistentSampleMapRecords::Release(const void* user) {
-  DCHECK_EQ(user_, user);
-  user_ = nullptr;
-}
-
-PersistentMemoryAllocator::Reference PersistentSampleMapRecords::GetNext() {
-  DCHECK(user_);
-
-  // If there are no unseen records, lock and swap in all the found ones.
-  if (records_.size() == seen_) {
-    if (!data_manager_->LoadRecords(this))
-      return false;
-  }
-
-  // Return the next record. Records *must* be returned in the same order
-  // they are found in the persistent memory in order to ensure that all
-  // objects using this data always have the same state. Race conditions
-  // can cause duplicate records so using the "first found" is the only
-  // guarantee that all objects always access the same one.
-  DCHECK_LT(seen_, records_.size());
-  return records_[seen_++];
-}
-
-PersistentMemoryAllocator::Reference PersistentSampleMapRecords::CreateNew(
-    HistogramBase::Sample value) {
-  return PersistentSampleMap::CreatePersistentRecord(data_manager_->allocator_,
-                                                     sample_map_id_, value);
-}
-
-
-// This data will be held in persistent memory in order for processes to
-// locate and use histograms created elsewhere.
-struct PersistentHistogramAllocator::PersistentHistogramData {
-  // SHA1(Histogram): Increment this if structure changes!
-  static constexpr uint32_t kPersistentTypeId = 0xF1645910 + 3;
-
-  // Expected size for 32/64-bit check.
-  static constexpr size_t kExpectedInstanceSize =
-      40 + 2 * HistogramSamples::Metadata::kExpectedInstanceSize;
-
-  int32_t histogram_type;
-  int32_t flags;
-  int32_t minimum;
-  int32_t maximum;
-  uint32_t bucket_count;
-  PersistentMemoryAllocator::Reference ranges_ref;
-  uint32_t ranges_checksum;
-  subtle::Atomic32 counts_ref;  // PersistentMemoryAllocator::Reference
-  HistogramSamples::Metadata samples_metadata;
-  HistogramSamples::Metadata logged_metadata;
-
-  // Space for the histogram name will be added during the actual allocation
-  // request. This must be the last field of the structure. A zero-size array
-  // or a "flexible" array would be preferred but is not (yet) valid C++.
-  char name[sizeof(uint64_t)];  // Force 64-bit alignment on 32-bit builds.
-};
-
-PersistentHistogramAllocator::Iterator::Iterator(
-    PersistentHistogramAllocator* allocator)
-    : allocator_(allocator), memory_iter_(allocator->memory_allocator()) {}
-
-std::unique_ptr<HistogramBase>
-PersistentHistogramAllocator::Iterator::GetNextWithIgnore(Reference ignore) {
-  PersistentMemoryAllocator::Reference ref;
-  while ((ref = memory_iter_.GetNextOfType<PersistentHistogramData>()) != 0) {
-    if (ref != ignore)
-      return allocator_->GetHistogram(ref);
-  }
-  return nullptr;
-}
-
-
-PersistentHistogramAllocator::PersistentHistogramAllocator(
-    std::unique_ptr<PersistentMemoryAllocator> memory)
-    : memory_allocator_(std::move(memory)),
-      sparse_histogram_data_manager_(memory_allocator_.get()) {}
-
-PersistentHistogramAllocator::~PersistentHistogramAllocator() = default;
-
-std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
-    Reference ref) {
-  // Unfortunately, the histogram "pickle" methods cannot be used as part of
-  // the persistance because the deserialization methods always create local
-  // count data (while these must reference the persistent counts) and always
-  // add it to the local list of known histograms (while these may be simple
-  // references to histograms in other processes).
-  PersistentHistogramData* data =
-      memory_allocator_->GetAsObject<PersistentHistogramData>(ref);
-  const size_t length = memory_allocator_->GetAllocSize(ref);
-
-  // Check that metadata is reasonable: name is null-terminated and non-empty,
-  // ID fields have been loaded with a hash of the name (0 is considered
-  // unset/invalid).
-  if (!data || data->name[0] == '\0' ||
-      reinterpret_cast<char*>(data)[length - 1] != '\0' ||
-      data->samples_metadata.id == 0 || data->logged_metadata.id == 0 ||
-      // Note: Sparse histograms use |id + 1| in |logged_metadata|.
-      (data->logged_metadata.id != data->samples_metadata.id &&
-       data->logged_metadata.id != data->samples_metadata.id + 1) ||
-      // Most non-matching values happen due to truncated names. Ideally, we
-      // 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(data->name) != data->samples_metadata.id) {
-    NOTREACHED();
-    return nullptr;
-  }
-  return CreateHistogram(data);
-}
-
-std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
-    HistogramType histogram_type,
-    const std::string& name,
-    int minimum,
-    int maximum,
-    const BucketRanges* bucket_ranges,
-    int32_t flags,
-    Reference* ref_ptr) {
-  // If the allocator is corrupt, don't waste time trying anything else.
-  // This also allows differentiating on the dashboard between allocations
-  // failed due to a corrupt allocator and the number of process instances
-  // with one, the latter being idicated by "newly corrupt", below.
-  if (memory_allocator_->IsCorrupt())
-    return nullptr;
-
-  // Create the metadata necessary for a persistent sparse histogram. This
-  // is done first because it is a small subset of what is required for
-  // other histograms. The type is "under construction" so that a crash
-  // during the datafill doesn't leave a bad record around that could cause
-  // confusion by another process trying to read it. It will be corrected
-  // once histogram construction is complete.
-  PersistentHistogramData* histogram_data =
-      memory_allocator_->New<PersistentHistogramData>(
-          offsetof(PersistentHistogramData, name) + name.length() + 1);
-  if (histogram_data) {
-    memcpy(histogram_data->name, name.c_str(), name.size() + 1);
-    histogram_data->histogram_type = histogram_type;
-    histogram_data->flags = flags | HistogramBase::kIsPersistent;
-  }
-
-  // Create the remaining metadata necessary for regular histograms.
-  if (histogram_type != SPARSE_HISTOGRAM) {
-    size_t bucket_count = bucket_ranges->bucket_count();
-    size_t counts_bytes = CalculateRequiredCountsBytes(bucket_count);
-    if (counts_bytes == 0) {
-      // |bucket_count| was out-of-range.
-      NOTREACHED();
-      return nullptr;
-    }
-
-    // Since the StasticsRecorder keeps a global collection of BucketRanges
-    // objects for re-use, it would be dangerous for one to hold a reference
-    // from a persistent allocator that is not the global one (which is
-    // permanent once set). If this stops being the case, this check can
-    // become an "if" condition beside "!ranges_ref" below and before
-    // set_persistent_reference() farther down.
-    DCHECK_EQ(this, GlobalHistogramAllocator::Get());
-
-    // Re-use an existing BucketRanges persistent allocation if one is known;
-    // otherwise, create one.
-    PersistentMemoryAllocator::Reference ranges_ref =
-        bucket_ranges->persistent_reference();
-    if (!ranges_ref) {
-      size_t ranges_count = bucket_count + 1;
-      size_t ranges_bytes = ranges_count * sizeof(HistogramBase::Sample);
-      ranges_ref =
-          memory_allocator_->Allocate(ranges_bytes, kTypeIdRangesArray);
-      if (ranges_ref) {
-        HistogramBase::Sample* ranges_data =
-            memory_allocator_->GetAsArray<HistogramBase::Sample>(
-                ranges_ref, kTypeIdRangesArray, ranges_count);
-        if (ranges_data) {
-          for (size_t i = 0; i < bucket_ranges->size(); ++i)
-            ranges_data[i] = bucket_ranges->range(i);
-          bucket_ranges->set_persistent_reference(ranges_ref);
-        } else {
-          // This should never happen but be tolerant if it does.
-          NOTREACHED();
-          ranges_ref = PersistentMemoryAllocator::kReferenceNull;
-        }
-      }
-    } else {
-      DCHECK_EQ(kTypeIdRangesArray, memory_allocator_->GetType(ranges_ref));
-    }
-
-
-    // Only continue here if all allocations were successful. If they weren't,
-    // there is no way to free the space but that's not really a problem since
-    // the allocations only fail because the space is full or corrupt and so
-    // any future attempts will also fail.
-    if (ranges_ref && histogram_data) {
-      histogram_data->minimum = minimum;
-      histogram_data->maximum = maximum;
-      // |bucket_count| must fit within 32-bits or the allocation of the counts
-      // array would have failed for being too large; the allocator supports
-      // less than 4GB total size.
-      histogram_data->bucket_count = static_cast<uint32_t>(bucket_count);
-      histogram_data->ranges_ref = ranges_ref;
-      histogram_data->ranges_checksum = bucket_ranges->checksum();
-    } else {
-      histogram_data = nullptr;  // Clear this for proper handling below.
-    }
-  }
-
-  if (histogram_data) {
-    // Create the histogram using resources in persistent memory. This ends up
-    // resolving the "ref" values stored in histogram_data instad of just
-    // 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);
-    DCHECK(histogram);
-    DCHECK_NE(0U, histogram_data->samples_metadata.id);
-    DCHECK_NE(0U, histogram_data->logged_metadata.id);
-
-    PersistentMemoryAllocator::Reference histogram_ref =
-        memory_allocator_->GetAsReference(histogram_data);
-    if (ref_ptr != nullptr)
-      *ref_ptr = histogram_ref;
-
-    // By storing the reference within the allocator to this histogram, the
-    // next import (which will happen before the next histogram creation)
-    // will know to skip it.
-    // See also the comment in ImportHistogramsToStatisticsRecorder().
-    subtle::NoBarrier_Store(&last_created_, histogram_ref);
-    return histogram;
-  }
-
-  if (memory_allocator_->IsCorrupt())
-    NOTREACHED() << memory_allocator_->Name() << " is corrupt!";
-
-  return nullptr;
-}
-
-void PersistentHistogramAllocator::FinalizeHistogram(Reference ref,
-                                                     bool registered) {
-  if (registered) {
-    // If the created persistent histogram was registered then it needs to
-    // be marked as "iterable" in order to be found by other processes. This
-    // happens only after the histogram is fully formed so it's impossible for
-    // code iterating through the allocator to read a partially created record.
-    memory_allocator_->MakeIterable(ref);
-  } else {
-    // If it wasn't registered then a race condition must have caused two to
-    // be created. The allocator does not support releasing the acquired memory
-    // so just change the type to be empty.
-    memory_allocator_->ChangeType(ref, 0,
-                                  PersistentHistogramData::kPersistentTypeId,
-                                  /*clear=*/false);
-  }
-}
-
-void PersistentHistogramAllocator::MergeHistogramDeltaToStatisticsRecorder(
-    HistogramBase* histogram) {
-  DCHECK(histogram);
-
-  HistogramBase* existing = GetOrCreateStatisticsRecorderHistogram(histogram);
-  if (!existing) {
-    // The above should never fail but if it does, no real harm is done.
-    // The data won't be merged but it also won't be recorded as merged
-    // so a future try, if successful, will get what was missed. If it
-    // continues to fail, some metric data will be lost but that is better
-    // than crashing.
-    NOTREACHED();
-    return;
-  }
-
-  // Merge the delta from the passed object to the one in the SR.
-  existing->AddSamples(*histogram->SnapshotDelta());
-}
-
-void PersistentHistogramAllocator::MergeHistogramFinalDeltaToStatisticsRecorder(
-    const HistogramBase* histogram) {
-  DCHECK(histogram);
-
-  HistogramBase* existing = GetOrCreateStatisticsRecorderHistogram(histogram);
-  if (!existing) {
-    // The above should never fail but if it does, no real harm is done.
-    // Some metric data will be lost but that is better than crashing.
-    NOTREACHED();
-    return;
-  }
-
-  // Merge the delta from the passed object to the one in the SR.
-  existing->AddSamples(*histogram->SnapshotFinalDelta());
-}
-
-PersistentSampleMapRecords* PersistentHistogramAllocator::UseSampleMapRecords(
-    uint64_t id,
-    const void* user) {
-  return sparse_histogram_data_manager_.UseSampleMapRecords(id, user);
-}
-
-void PersistentHistogramAllocator::CreateTrackingHistograms(StringPiece name) {
-  memory_allocator_->CreateTrackingHistograms(name);
-}
-
-void PersistentHistogramAllocator::UpdateTrackingHistograms() {
-  memory_allocator_->UpdateTrackingHistograms();
-}
-
-void PersistentHistogramAllocator::ClearLastCreatedReferenceForTesting() {
-  subtle::NoBarrier_Store(&last_created_, 0);
-}
-
-std::unique_ptr<HistogramBase> PersistentHistogramAllocator::CreateHistogram(
-    PersistentHistogramData* histogram_data_ptr) {
-  if (!histogram_data_ptr) {
-    NOTREACHED();
-    return nullptr;
-  }
-
-  // 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,
-                                          &histogram_data_ptr->samples_metadata,
-                                          &histogram_data_ptr->logged_metadata);
-    DCHECK(histogram);
-    histogram->SetFlags(histogram_data_ptr->flags);
-    return histogram;
-  }
-
-  // Copy the configuration fields from histogram_data_ptr to local storage
-  // because anything in persistent memory cannot be trusted as it could be
-  // changed at any moment by a malicious actor that shares access. The local
-  // values are validated below and then used to create the histogram, knowing
-  // they haven't changed between validation and use.
-  int32_t histogram_type = histogram_data_ptr->histogram_type;
-  int32_t histogram_flags = histogram_data_ptr->flags;
-  int32_t histogram_minimum = histogram_data_ptr->minimum;
-  int32_t histogram_maximum = histogram_data_ptr->maximum;
-  uint32_t histogram_bucket_count = histogram_data_ptr->bucket_count;
-  uint32_t histogram_ranges_ref = histogram_data_ptr->ranges_ref;
-  uint32_t histogram_ranges_checksum = histogram_data_ptr->ranges_checksum;
-
-  HistogramBase::Sample* ranges_data =
-      memory_allocator_->GetAsArray<HistogramBase::Sample>(
-          histogram_ranges_ref, kTypeIdRangesArray,
-          PersistentMemoryAllocator::kSizeAny);
-
-  const uint32_t max_buckets =
-      std::numeric_limits<uint32_t>::max() / sizeof(HistogramBase::Sample);
-  size_t required_bytes =
-      (histogram_bucket_count + 1) * sizeof(HistogramBase::Sample);
-  size_t allocated_bytes =
-      memory_allocator_->GetAllocSize(histogram_ranges_ref);
-  if (!ranges_data || histogram_bucket_count < 2 ||
-      histogram_bucket_count >= max_buckets ||
-      allocated_bytes < required_bytes) {
-    NOTREACHED();
-    return nullptr;
-  }
-
-  std::unique_ptr<const BucketRanges> created_ranges = CreateRangesFromData(
-      ranges_data, histogram_ranges_checksum, histogram_bucket_count + 1);
-  if (!created_ranges) {
-    NOTREACHED();
-    return nullptr;
-  }
-  const BucketRanges* ranges =
-      StatisticsRecorder::RegisterOrDeleteDuplicateRanges(
-          created_ranges.release());
-
-  size_t counts_bytes = CalculateRequiredCountsBytes(histogram_bucket_count);
-  PersistentMemoryAllocator::Reference counts_ref =
-      subtle::Acquire_Load(&histogram_data_ptr->counts_ref);
-  if (counts_bytes == 0 ||
-      (counts_ref != 0 &&
-       memory_allocator_->GetAllocSize(counts_ref) < counts_bytes)) {
-    NOTREACHED();
-    return nullptr;
-  }
-
-  // The "counts" data (including both samples and logged samples) is a delayed
-  // persistent allocation meaning that though its size and storage for a
-  // reference is defined, no space is reserved until actually needed. When
-  // it is needed, memory will be allocated from the persistent segment and
-  // a reference to it stored at the passed address. Other threads can then
-  // notice the valid reference and access the same data.
-  DelayedPersistentAllocation counts_data(memory_allocator_.get(),
-                                          &histogram_data_ptr->counts_ref,
-                                          kTypeIdCountsArray, counts_bytes, 0);
-
-  // A second delayed allocations is defined using the same reference storage
-  // location as the first so the allocation of one will automatically be found
-  // by the other. Within the block, the first half of the space is for "counts"
-  // and the second half is for "logged counts".
-  DelayedPersistentAllocation logged_data(
-      memory_allocator_.get(), &histogram_data_ptr->counts_ref,
-      kTypeIdCountsArray, counts_bytes, counts_bytes / 2,
-      /*make_iterable=*/false);
-
-  // 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, histogram_minimum, histogram_maximum, 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, histogram_minimum, histogram_maximum, 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,
-          &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,
-          &histogram_data_ptr->samples_metadata,
-          &histogram_data_ptr->logged_metadata);
-      DCHECK(histogram);
-      break;
-    default:
-      NOTREACHED();
-  }
-
-  if (histogram) {
-    DCHECK_EQ(histogram_type, histogram->GetHistogramType());
-    histogram->SetFlags(histogram_flags);
-  }
-
-  return histogram;
-}
-
-HistogramBase*
-PersistentHistogramAllocator::GetOrCreateStatisticsRecorderHistogram(
-    const HistogramBase* histogram) {
-  // This should never be called on the global histogram allocator as objects
-  // created there are already within the global statistics recorder.
-  DCHECK_NE(GlobalHistogramAllocator::Get(), this);
-  DCHECK(histogram);
-
-  HistogramBase* existing =
-      StatisticsRecorder::FindHistogram(histogram->histogram_name());
-  if (existing)
-    return existing;
-
-  // Adding the passed histogram to the SR would cause a problem if the
-  // allocator that holds it eventually goes away. Instead, create a new
-  // one from a serialized version. Deserialization calls the appropriate
-  // FactoryGet() which will create the histogram in the global persistent-
-  // histogram allocator if such is set.
-  base::Pickle pickle;
-  histogram->SerializeInfo(&pickle);
-  PickleIterator iter(pickle);
-  existing = DeserializeHistogramInfo(&iter);
-  if (!existing)
-    return nullptr;
-
-  // Make sure there is no "serialization" flag set.
-  DCHECK_EQ(0, existing->flags() & HistogramBase::kIPCSerializationSourceFlag);
-  // Record the newly created histogram in the SR.
-  return StatisticsRecorder::RegisterOrDeleteDuplicate(existing);
-}
-
-GlobalHistogramAllocator::~GlobalHistogramAllocator() = default;
-
-// static
-void GlobalHistogramAllocator::CreateWithPersistentMemory(
-    void* base,
-    size_t size,
-    size_t page_size,
-    uint64_t id,
-    StringPiece name) {
-  Set(WrapUnique(
-      new GlobalHistogramAllocator(std::make_unique<PersistentMemoryAllocator>(
-          base, size, page_size, id, name, false))));
-}
-
-// static
-void GlobalHistogramAllocator::CreateWithLocalMemory(
-    size_t size,
-    uint64_t id,
-    StringPiece name) {
-  Set(WrapUnique(new GlobalHistogramAllocator(
-      std::make_unique<LocalPersistentMemoryAllocator>(size, id, name))));
-}
-
-#if !defined(OS_NACL)
-// static
-bool GlobalHistogramAllocator::CreateWithFile(
-    const FilePath& file_path,
-    size_t size,
-    uint64_t id,
-    StringPiece name) {
-  bool exists = PathExists(file_path);
-  File file(
-      file_path, File::FLAG_OPEN_ALWAYS | File::FLAG_SHARE_DELETE |
-                 File::FLAG_READ | File::FLAG_WRITE);
-
-  std::unique_ptr<MemoryMappedFile> mmfile(new MemoryMappedFile());
-  if (exists) {
-    size = saturated_cast<size_t>(file.GetLength());
-    mmfile->Initialize(std::move(file), MemoryMappedFile::READ_WRITE);
-  } else {
-    mmfile->Initialize(std::move(file), {0, size},
-                       MemoryMappedFile::READ_WRITE_EXTEND);
-  }
-  if (!mmfile->IsValid() ||
-      !FilePersistentMemoryAllocator::IsFileAcceptable(*mmfile, true)) {
-    NOTREACHED() << file_path;
-    return false;
-  }
-
-  Set(WrapUnique(new GlobalHistogramAllocator(
-      std::make_unique<FilePersistentMemoryAllocator>(std::move(mmfile), size,
-                                                      id, name, false))));
-  Get()->SetPersistentLocation(file_path);
-  return true;
-}
-
-// static
-bool GlobalHistogramAllocator::CreateWithActiveFile(const FilePath& base_path,
-                                                    const FilePath& active_path,
-                                                    const FilePath& spare_path,
-                                                    size_t size,
-                                                    uint64_t id,
-                                                    StringPiece name) {
-  // Old "active" becomes "base".
-  if (!base::ReplaceFile(active_path, base_path, nullptr))
-    base::DeleteFile(base_path, /*recursive=*/false);
-  DCHECK(!base::PathExists(active_path));
-
-  // Move any "spare" into "active". Okay to continue if file doesn't exist.
-  if (!spare_path.empty()) {
-    base::ReplaceFile(spare_path, active_path, nullptr);
-    DCHECK(!base::PathExists(spare_path));
-  }
-
-  return base::GlobalHistogramAllocator::CreateWithFile(active_path, size, id,
-                                                        name);
-}
-
-// static
-bool GlobalHistogramAllocator::CreateWithActiveFileInDir(const FilePath& dir,
-                                                         size_t size,
-                                                         uint64_t id,
-                                                         StringPiece name) {
-  FilePath base_path, active_path, spare_path;
-  ConstructFilePaths(dir, name, &base_path, &active_path, &spare_path);
-  return CreateWithActiveFile(base_path, active_path, spare_path, size, id,
-                              name);
-}
-
-// static
-FilePath GlobalHistogramAllocator::ConstructFilePath(const FilePath& dir,
-                                                     StringPiece name) {
-  return dir.AppendASCII(name).AddExtension(
-      PersistentMemoryAllocator::kFileExtension);
-}
-
-// static
-FilePath GlobalHistogramAllocator::ConstructFilePathForUploadDir(
-    const FilePath& dir,
-    StringPiece name,
-    base::Time stamp,
-    ProcessId pid) {
-  return ConstructFilePath(
-      dir,
-      StringPrintf("%.*s-%lX-%lX", static_cast<int>(name.length()), name.data(),
-                   static_cast<long>(stamp.ToTimeT()), static_cast<long>(pid)));
-}
-
-// static
-bool GlobalHistogramAllocator::ParseFilePath(const FilePath& path,
-                                             std::string* out_name,
-                                             Time* out_stamp,
-                                             ProcessId* out_pid) {
-  std::string filename = path.BaseName().AsUTF8Unsafe();
-  std::vector<base::StringPiece> parts = base::SplitStringPiece(
-      filename, "-.", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
-  if (parts.size() != 4)
-    return false;
-
-  if (out_name)
-    *out_name = parts[0].as_string();
-
-  if (out_stamp) {
-    int64_t stamp;
-    if (!HexStringToInt64(parts[1], &stamp))
-      return false;
-    *out_stamp = Time::FromTimeT(static_cast<time_t>(stamp));
-  }
-
-  if (out_pid) {
-    int64_t pid;
-    if (!HexStringToInt64(parts[2], &pid))
-      return false;
-    *out_pid = static_cast<ProcessId>(pid);
-  }
-
-  return true;
-}
-
-// static
-void GlobalHistogramAllocator::ConstructFilePaths(const FilePath& dir,
-                                                  StringPiece name,
-                                                  FilePath* out_base_path,
-                                                  FilePath* out_active_path,
-                                                  FilePath* out_spare_path) {
-  if (out_base_path)
-    *out_base_path = ConstructFilePath(dir, name);
-
-  if (out_active_path) {
-    *out_active_path =
-        ConstructFilePath(dir, name.as_string().append("-active"));
-  }
-
-  if (out_spare_path) {
-    *out_spare_path = ConstructFilePath(dir, name.as_string().append("-spare"));
-  }
-}
-
-// static
-void GlobalHistogramAllocator::ConstructFilePathsForUploadDir(
-    const FilePath& active_dir,
-    const FilePath& upload_dir,
-    const std::string& name,
-    FilePath* out_upload_path,
-    FilePath* out_active_path,
-    FilePath* out_spare_path) {
-  if (out_upload_path) {
-    *out_upload_path = ConstructFilePathForUploadDir(
-        upload_dir, name, Time::Now(), GetCurrentProcId());
-  }
-
-  if (out_active_path) {
-    *out_active_path =
-        ConstructFilePath(active_dir, name + std::string("-active"));
-  }
-
-  if (out_spare_path) {
-    *out_spare_path =
-        ConstructFilePath(active_dir, name + std::string("-spare"));
-  }
-}
-
-// static
-bool GlobalHistogramAllocator::CreateSpareFile(const FilePath& spare_path,
-                                               size_t size) {
-  FilePath temp_spare_path = spare_path.AddExtension(FILE_PATH_LITERAL(".tmp"));
-  bool success = true;
-  {
-    File spare_file(temp_spare_path, File::FLAG_CREATE_ALWAYS |
-                                         File::FLAG_READ | File::FLAG_WRITE);
-    if (!spare_file.IsValid())
-      return false;
-
-    MemoryMappedFile mmfile;
-    mmfile.Initialize(std::move(spare_file), {0, size},
-                      MemoryMappedFile::READ_WRITE_EXTEND);
-    success = mmfile.IsValid();
-  }
-
-  if (success)
-    success = ReplaceFile(temp_spare_path, spare_path, nullptr);
-
-  if (!success)
-    DeleteFile(temp_spare_path, /*recursive=*/false);
-
-  return success;
-}
-
-// static
-bool GlobalHistogramAllocator::CreateSpareFileInDir(const FilePath& dir,
-                                                    size_t size,
-                                                    StringPiece name) {
-  FilePath spare_path;
-  ConstructFilePaths(dir, name, nullptr, nullptr, &spare_path);
-  return CreateSpareFile(spare_path, size);
-}
-#endif  // !defined(OS_NACL)
-
-// static
-void GlobalHistogramAllocator::CreateWithSharedMemoryHandle(
-    const SharedMemoryHandle& handle,
-    size_t size) {
-  std::unique_ptr<SharedMemory> shm(
-      new SharedMemory(handle, /*readonly=*/false));
-  if (!shm->Map(size) ||
-      !SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(*shm)) {
-    NOTREACHED();
-    return;
-  }
-
-  Set(WrapUnique(new GlobalHistogramAllocator(
-      std::make_unique<SharedPersistentMemoryAllocator>(
-          std::move(shm), 0, StringPiece(), /*readonly=*/false))));
-}
-
-// static
-void GlobalHistogramAllocator::Set(
-    std::unique_ptr<GlobalHistogramAllocator> allocator) {
-  // Releasing or changing an allocator is extremely dangerous because it
-  // likely has histograms stored within it. If the backing memory is also
-  // also released, future accesses to those histograms will seg-fault.
-  CHECK(!subtle::NoBarrier_Load(&g_histogram_allocator));
-  subtle::Release_Store(&g_histogram_allocator,
-                        reinterpret_cast<uintptr_t>(allocator.release()));
-  size_t existing = StatisticsRecorder::GetHistogramCount();
-
-  DVLOG_IF(1, existing)
-      << existing << " histograms were created before persistence was enabled.";
-}
-
-// static
-GlobalHistogramAllocator* GlobalHistogramAllocator::Get() {
-  return reinterpret_cast<GlobalHistogramAllocator*>(
-      subtle::Acquire_Load(&g_histogram_allocator));
-}
-
-// static
-std::unique_ptr<GlobalHistogramAllocator>
-GlobalHistogramAllocator::ReleaseForTesting() {
-  GlobalHistogramAllocator* histogram_allocator = Get();
-  if (!histogram_allocator)
-    return nullptr;
-  PersistentMemoryAllocator* memory_allocator =
-      histogram_allocator->memory_allocator();
-
-  // Before releasing the memory, it's necessary to have the Statistics-
-  // Recorder forget about the histograms contained therein; otherwise,
-  // some operations will try to access them and the released memory.
-  PersistentMemoryAllocator::Iterator iter(memory_allocator);
-  const PersistentHistogramData* data;
-  while ((data = iter.GetNextOfObject<PersistentHistogramData>()) != nullptr) {
-    StatisticsRecorder::ForgetHistogramForTesting(data->name);
-  }
-
-  subtle::Release_Store(&g_histogram_allocator, 0);
-  return WrapUnique(histogram_allocator);
-};
-
-void GlobalHistogramAllocator::SetPersistentLocation(const FilePath& location) {
-  persistent_location_ = location;
-}
-
-const FilePath& GlobalHistogramAllocator::GetPersistentLocation() const {
-  return persistent_location_;
-}
-
-bool GlobalHistogramAllocator::WriteToPersistentLocation() {
-#if defined(OS_NACL)
-  // NACL doesn't support file operations, including ImportantFileWriter.
-  NOTREACHED();
-  return false;
-#else
-  // Stop if no destination is set.
-  if (persistent_location_.empty()) {
-    NOTREACHED() << "Could not write \"" << Name() << "\" persistent histograms"
-                 << " to file because no location was set.";
-    return false;
-  }
-
-  StringPiece contents(static_cast<const char*>(data()), used());
-  if (!ImportantFileWriter::WriteFileAtomically(persistent_location_,
-                                                contents)) {
-    LOG(ERROR) << "Could not write \"" << Name() << "\" persistent histograms"
-               << " to file: " << persistent_location_.value();
-    return false;
-  }
-
-  return true;
-#endif
-}
-
-void GlobalHistogramAllocator::DeletePersistentLocation() {
-  memory_allocator()->SetMemoryState(PersistentMemoryAllocator::MEMORY_DELETED);
-
-#if defined(OS_NACL)
-  NOTREACHED();
-#else
-  if (persistent_location_.empty())
-    return;
-
-  // Open (with delete) and then immediately close the file by going out of
-  // scope. This is the only cross-platform safe way to delete a file that may
-  // be open elsewhere. Open handles will continue to operate normally but
-  // new opens will not be possible.
-  File file(persistent_location_,
-            File::FLAG_OPEN | File::FLAG_READ | File::FLAG_DELETE_ON_CLOSE);
-#endif
-}
-
-GlobalHistogramAllocator::GlobalHistogramAllocator(
-    std::unique_ptr<PersistentMemoryAllocator> memory)
-    : PersistentHistogramAllocator(std::move(memory)),
-      import_iterator_(this) {
-}
-
-void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() {
-  // Skip the import if it's the histogram that was last created. Should a
-  // race condition cause the "last created" to be overwritten before it
-  // is recognized here then the histogram will be created and be ignored
-  // when it is detected as a duplicate by the statistics-recorder. This
-  // simple check reduces the time of creating persistent histograms by
-  // about 40%.
-  Reference record_to_ignore = last_created();
-
-  // There is no lock on this because the iterator is lock-free while still
-  // guaranteed to only return each entry only once. The StatisticsRecorder
-  // has its own lock so the Register operation is safe.
-  while (true) {
-    std::unique_ptr<HistogramBase> histogram =
-        import_iterator_.GetNextWithIgnore(record_to_ignore);
-    if (!histogram)
-      break;
-    StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release());
-  }
-}
-
-}  // namespace base
diff --git a/base/metrics/persistent_histogram_allocator.h b/base/metrics/persistent_histogram_allocator.h
deleted file mode 100644
index 395511f..0000000
--- a/base/metrics/persistent_histogram_allocator.h
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
-#define BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
-
-#include <map>
-#include <memory>
-
-#include "base/atomicops.h"
-#include "base/base_export.h"
-#include "base/feature_list.h"
-#include "base/memory/shared_memory.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/persistent_memory_allocator.h"
-#include "base/strings/string_piece.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-class BucketRanges;
-class FilePath;
-class PersistentSampleMapRecords;
-class PersistentSparseHistogramDataManager;
-
-// Feature definition for enabling histogram persistence.
-BASE_EXPORT extern const Feature kPersistentHistogramsFeature;
-
-
-// A data manager for sparse histograms so each instance of such doesn't have
-// to separately iterate over the entire memory segment. Though this class
-// will generally be accessed through the PersistentHistogramAllocator above,
-// it can be used independently on any PersistentMemoryAllocator (making it
-// useable for testing). This object supports only one instance of a sparse
-// histogram for a given id. Tests that create multiple identical histograms,
-// perhaps to simulate multiple processes, should create a separate manager
-// for each.
-class BASE_EXPORT PersistentSparseHistogramDataManager {
- public:
-  // Constructs the data manager. The allocator must live longer than any
-  // managers that reference it.
-  explicit PersistentSparseHistogramDataManager(
-      PersistentMemoryAllocator* allocator);
-
-  ~PersistentSparseHistogramDataManager();
-
-  // Returns the object that manages the persistent-sample-map records for a
-  // given |id|. Only one |user| of this data is allowed at a time. This does
-  // an automatic Acquire() on the records. The user must call Release() on
-  // the returned object when it is finished with it. Ownership of the records
-  // object stays with this manager.
-  PersistentSampleMapRecords* UseSampleMapRecords(uint64_t id,
-                                                  const void* user);
-
-  // Convenience method that gets the object for a given reference so callers
-  // don't have to also keep their own pointer to the appropriate allocator.
-  template <typename T>
-  T* GetAsObject(PersistentMemoryAllocator::Reference ref) {
-    return allocator_->GetAsObject<T>(ref);
-  }
-
- private:
-  friend class PersistentSampleMapRecords;
-
-  // Gets the object holding records for a given sample-map id when |lock_|
-  // has already been acquired.
-  PersistentSampleMapRecords* GetSampleMapRecordsWhileLocked(uint64_t id);
-
-  // Loads sample-map records looking for those belonging to the specified
-  // |load_id|. Records found for other sample-maps are held for later use
-  // without having to iterate again. This should be called only from a
-  // PersistentSampleMapRecords object because those objects have a contract
-  // that there are no other threads accessing the internal records_ field
-  // of the object that is passed in.
-  bool LoadRecords(PersistentSampleMapRecords* sample_map_records);
-
-  // Weak-pointer to the allocator used by the sparse histograms.
-  PersistentMemoryAllocator* allocator_;
-
-  // Iterator within the allocator for finding sample records.
-  PersistentMemoryAllocator::Iterator record_iterator_;
-
-  // Mapping of sample-map IDs to their sample records.
-  std::map<uint64_t, std::unique_ptr<PersistentSampleMapRecords>>
-      sample_records_;
-
-  // A lock used for synchronizing changes to sample_records_.
-  base::Lock lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(PersistentSparseHistogramDataManager);
-};
-
-
-// This class manages sample-records used by a PersistentSampleMap container
-// that underlies a persistent SparseHistogram object. It is broken out into a
-// top-level class so that it can be forward-declared in other header files
-// rather than include this entire file as would be necessary if it were
-// declared within the PersistentSparseHistogramDataManager class above.
-class BASE_EXPORT PersistentSampleMapRecords {
- public:
-  // Constructs an instance of this class. The manager object must live longer
-  // than all instances of this class that reference it, which is not usually
-  // a problem since these objects are generally managed from within that
-  // manager instance.
-  PersistentSampleMapRecords(PersistentSparseHistogramDataManager* data_manager,
-                             uint64_t sample_map_id);
-
-  ~PersistentSampleMapRecords();
-
-  // Resets the internal state for a new object using this data. The return
-  // value is "this" as a convenience.
-  PersistentSampleMapRecords* Acquire(const void* user);
-
-  // Indicates that the using object is done with this data.
-  void Release(const void* user);
-
-  // Gets the next reference to a persistent sample-map record. The type and
-  // layout of the data being referenced is defined entirely within the
-  // PersistentSampleMap class.
-  PersistentMemoryAllocator::Reference GetNext();
-
-  // Creates a new persistent sample-map record for sample |value| and returns
-  // a reference to it.
-  PersistentMemoryAllocator::Reference CreateNew(HistogramBase::Sample value);
-
-  // Convenience method that gets the object for a given reference so callers
-  // don't have to also keep their own pointer to the appropriate allocator.
-  // This is expected to be used with the SampleRecord structure defined inside
-  // the persistent_sample_map.cc file but since that isn't exported (for
-  // cleanliness of the interface), a template is defined that will be
-  // resolved when used inside that file.
-  template <typename T>
-  T* GetAsObject(PersistentMemoryAllocator::Reference ref) {
-    return data_manager_->GetAsObject<T>(ref);
-  }
-
- private:
-  friend PersistentSparseHistogramDataManager;
-
-  // Weak-pointer to the parent data-manager object.
-  PersistentSparseHistogramDataManager* data_manager_;
-
-  // ID of PersistentSampleMap to which these records apply.
-  const uint64_t sample_map_id_;
-
-  // The current user of this set of records. It is used to ensure that no
-  // more than one object is using these records at a given time.
-  const void* user_ = nullptr;
-
-  // This is the count of how many "records" have already been read by the
-  // owning sample-map.
-  size_t seen_ = 0;
-
-  // This is the set of records previously found for a sample map. Because
-  // there is ever only one object with a given ID (typically a hash of a
-  // histogram name) and because the parent SparseHistogram has acquired
-  // its own lock before accessing the PersistentSampleMap it controls, this
-  // list can be accessed without acquiring any additional lock.
-  std::vector<PersistentMemoryAllocator::Reference> records_;
-
-  // This is the set of records found during iteration through memory. It
-  // is appended in bulk to "records". Access to this vector can be done
-  // only while holding the parent manager's lock.
-  std::vector<PersistentMemoryAllocator::Reference> found_;
-
-  DISALLOW_COPY_AND_ASSIGN(PersistentSampleMapRecords);
-};
-
-
-// This class manages histograms created within a PersistentMemoryAllocator.
-class BASE_EXPORT PersistentHistogramAllocator {
- public:
-  // A reference to a histogram. While this is implemented as PMA::Reference,
-  // it is not conceptually the same thing. Outside callers should always use
-  // a Reference matching the class it is for and not mix the two.
-  using Reference = PersistentMemoryAllocator::Reference;
-
-  // Iterator used for fetching persistent histograms from an allocator.
-  // It is lock-free and thread-safe.
-  // See PersistentMemoryAllocator::Iterator for more information.
-  class BASE_EXPORT Iterator {
-   public:
-    // Constructs an iterator on a given |allocator|, starting at the beginning.
-    // The allocator must live beyond the lifetime of the iterator.
-    explicit Iterator(PersistentHistogramAllocator* allocator);
-
-    // Gets the next histogram from persistent memory; returns null if there
-    // are no more histograms to be found. This may still be called again
-    // later to retrieve any new histograms added in the meantime.
-    std::unique_ptr<HistogramBase> GetNext() { return GetNextWithIgnore(0); }
-
-    // Gets the next histogram from persistent memory, ignoring one particular
-    // reference in the process. Pass |ignore| of zero (0) to ignore nothing.
-    std::unique_ptr<HistogramBase> GetNextWithIgnore(Reference ignore);
-
-   private:
-    // Weak-pointer to histogram allocator being iterated over.
-    PersistentHistogramAllocator* allocator_;
-
-    // The iterator used for stepping through objects in persistent memory.
-    // It is lock-free and thread-safe which is why this class is also such.
-    PersistentMemoryAllocator::Iterator memory_iter_;
-
-    DISALLOW_COPY_AND_ASSIGN(Iterator);
-  };
-
-  // A PersistentHistogramAllocator is constructed from a PersistentMemory-
-  // Allocator object of which it takes ownership.
-  explicit PersistentHistogramAllocator(
-      std::unique_ptr<PersistentMemoryAllocator> memory);
-  virtual ~PersistentHistogramAllocator();
-
-  // Direct access to underlying memory allocator. If the segment is shared
-  // across threads or processes, reading data through these values does
-  // not guarantee consistency. Use with care. Do not write.
-  PersistentMemoryAllocator* memory_allocator() {
-    return memory_allocator_.get();
-  }
-
-  // Implement the "metadata" API of a PersistentMemoryAllocator, forwarding
-  // those requests to the real one.
-  uint64_t Id() const { return memory_allocator_->Id(); }
-  const char* Name() const { return memory_allocator_->Name(); }
-  const void* data() const { return memory_allocator_->data(); }
-  size_t length() const { return memory_allocator_->length(); }
-  size_t size() const { return memory_allocator_->size(); }
-  size_t used() const { return memory_allocator_->used(); }
-
-  // Recreate a Histogram from data held in persistent memory. Though this
-  // object will be local to the current process, the sample data will be
-  // shared with all other threads referencing it. This method takes a |ref|
-  // to where the top-level histogram data may be found in this allocator.
-  // This method will return null if any problem is detected with the data.
-  std::unique_ptr<HistogramBase> GetHistogram(Reference ref);
-
-  // Allocate a new persistent histogram. The returned histogram will not
-  // be able to be located by other allocators until it is "finalized".
-  std::unique_ptr<HistogramBase> AllocateHistogram(
-      HistogramType histogram_type,
-      const std::string& name,
-      int minimum,
-      int maximum,
-      const BucketRanges* bucket_ranges,
-      int32_t flags,
-      Reference* ref_ptr);
-
-  // Finalize the creation of the histogram, making it available to other
-  // processes if |registered| (as in: added to the StatisticsRecorder) is
-  // True, forgetting it otherwise.
-  void FinalizeHistogram(Reference ref, bool registered);
-
-  // Merges the data in a persistent histogram with one held globally by the
-  // StatisticsRecorder, updating the "logged" samples within the passed
-  // object so that repeated merges are allowed. Don't call this on a "global"
-  // allocator because histograms created there will already be in the SR.
-  void MergeHistogramDeltaToStatisticsRecorder(HistogramBase* histogram);
-
-  // As above but merge the "final" delta. No update of "logged" samples is
-  // done which means it can operate on read-only objects. It's essential,
-  // however, not to call this more than once or those final samples will
-  // get recorded again.
-  void MergeHistogramFinalDeltaToStatisticsRecorder(
-      const HistogramBase* histogram);
-
-  // Returns the object that manages the persistent-sample-map records for a
-  // given |id|. Only one |user| of this data is allowed at a time. This does
-  // an automatic Acquire() on the records. The user must call Release() on
-  // the returned object when it is finished with it. Ownership stays with
-  // this allocator.
-  PersistentSampleMapRecords* UseSampleMapRecords(uint64_t id,
-                                                  const void* user);
-
-  // Create internal histograms for tracking memory use and allocation sizes
-  // for allocator of |name| (which can simply be the result of Name()). This
-  // is done seperately from construction for situations such as when the
-  // histograms will be backed by memory provided by this very allocator.
-  //
-  // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml
-  // with the following histograms:
-  //    UMA.PersistentAllocator.name.Allocs
-  //    UMA.PersistentAllocator.name.UsedPct
-  void CreateTrackingHistograms(StringPiece name);
-  void UpdateTrackingHistograms();
-
-  // Clears the internal |last_created_| reference so testing can validate
-  // operation without that optimization.
-  void ClearLastCreatedReferenceForTesting();
-
- protected:
-  // The structure used to hold histogram data in persistent memory. It is
-  // defined and used entirely within the .cc file.
-  struct PersistentHistogramData;
-
-  // Gets the reference of the last histogram created, used to avoid
-  // trying to import what was just created.
-  PersistentHistogramAllocator::Reference last_created() {
-    return subtle::NoBarrier_Load(&last_created_);
-  }
-
-  // Gets the next histogram in persistent data based on iterator while
-  // ignoring a particular reference if it is found.
-  std::unique_ptr<HistogramBase> GetNextHistogramWithIgnore(Iterator* iter,
-                                                            Reference ignore);
-
- private:
-  // Create a histogram based on saved (persistent) information about it.
-  std::unique_ptr<HistogramBase> CreateHistogram(
-      PersistentHistogramData* histogram_data_ptr);
-
-  // Gets or creates an object in the global StatisticsRecorder matching
-  // the |histogram| passed. Null is returned if one was not found and
-  // one could not be created.
-  HistogramBase* GetOrCreateStatisticsRecorderHistogram(
-      const HistogramBase* histogram);
-
-  // The memory allocator that provides the actual histogram storage.
-  std::unique_ptr<PersistentMemoryAllocator> memory_allocator_;
-
-  // The data-manager used to improve performance of sparse histograms.
-  PersistentSparseHistogramDataManager sparse_histogram_data_manager_;
-
-  // A reference to the last-created histogram in the allocator, used to avoid
-  // trying to import what was just created.
-  // TODO(bcwhite): Change this to std::atomic<PMA::Reference> when available.
-  subtle::Atomic32 last_created_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(PersistentHistogramAllocator);
-};
-
-
-// A special case of the PersistentHistogramAllocator that operates on a
-// global scale, collecting histograms created through standard macros and
-// the FactoryGet() method.
-class BASE_EXPORT GlobalHistogramAllocator
-    : public PersistentHistogramAllocator {
- public:
-  ~GlobalHistogramAllocator() override;
-
-  // Create a global allocator using the passed-in memory |base|, |size|, and
-  // other parameters. Ownership of the memory segment remains with the caller.
-  static void CreateWithPersistentMemory(void* base,
-                                         size_t size,
-                                         size_t page_size,
-                                         uint64_t id,
-                                         StringPiece name);
-
-  // Create a global allocator using an internal block of memory of the
-  // specified |size| taken from the heap.
-  static void CreateWithLocalMemory(size_t size, uint64_t id, StringPiece name);
-
-#if !defined(OS_NACL)
-  // Create a global allocator by memory-mapping a |file|. If the file does
-  // not exist, it will be created with the specified |size|. If the file does
-  // exist, the allocator will use and add to its contents, ignoring the passed
-  // size in favor of the existing size. Returns whether the global allocator
-  // was set.
-  static bool CreateWithFile(const FilePath& file_path,
-                             size_t size,
-                             uint64_t id,
-                             StringPiece name);
-
-  // Creates a new file at |active_path|. If it already exists, it will first be
-  // moved to |base_path|. In all cases, any old file at |base_path| will be
-  // removed. If |spare_path| is non-empty and exists, that will be renamed and
-  // used as the active file. Otherwise, the file will be created using the
-  // given size, id, and name. Returns whether the global allocator was set.
-  static bool CreateWithActiveFile(const FilePath& base_path,
-                                   const FilePath& active_path,
-                                   const FilePath& spare_path,
-                                   size_t size,
-                                   uint64_t id,
-                                   StringPiece name);
-
-  // Uses ConstructBaseActivePairFilePaths() to build a pair of file names which
-  // are then used for CreateWithActiveFile(). |name| is used for both the
-  // internal name for the allocator and also for the name of the file inside
-  // |dir|.
-  static bool CreateWithActiveFileInDir(const FilePath& dir,
-                                        size_t size,
-                                        uint64_t id,
-                                        StringPiece name);
-
-  // Constructs a filename using a name.
-  static FilePath ConstructFilePath(const FilePath& dir, StringPiece name);
-
-  // Like above but with timestamp and pid for use in upload directories.
-  static FilePath ConstructFilePathForUploadDir(const FilePath& dir,
-                                                StringPiece name,
-                                                base::Time stamp,
-                                                ProcessId pid);
-
-  // Parses a filename to extract name, timestamp, and pid.
-  static bool ParseFilePath(const FilePath& path,
-                            std::string* out_name,
-                            Time* out_stamp,
-                            ProcessId* out_pid);
-
-  // Constructs a set of names in |dir| based on name that can be used for a
-  // base + active persistent memory mapped location for CreateWithActiveFile().
-  // The spare path is a file that can be pre-created and moved to be active
-  // without any startup penalty that comes from constructing the file. |name|
-  // will be used as the basename of the file inside |dir|. |out_base_path|,
-  // |out_active_path|, or |out_spare_path| may be null if not needed.
-  static void ConstructFilePaths(const FilePath& dir,
-                                 StringPiece name,
-                                 FilePath* out_base_path,
-                                 FilePath* out_active_path,
-                                 FilePath* out_spare_path);
-
-  // As above but puts the base files in a different "upload" directory. This
-  // is useful when moving all completed files into a single directory for easy
-  // upload management.
-  static void ConstructFilePathsForUploadDir(const FilePath& active_dir,
-                                             const FilePath& upload_dir,
-                                             const std::string& name,
-                                             FilePath* out_upload_path,
-                                             FilePath* out_active_path,
-                                             FilePath* out_spare_path);
-
-  // Create a "spare" file that can later be made the "active" file. This
-  // should be done on a background thread if possible.
-  static bool CreateSpareFile(const FilePath& spare_path, size_t size);
-
-  // Same as above but uses standard names. |name| is the name of the allocator
-  // and is also used to create the correct filename.
-  static bool CreateSpareFileInDir(const FilePath& dir_path,
-                                   size_t size,
-                                   StringPiece name);
-#endif
-
-  // Create a global allocator using a block of shared memory accessed
-  // through the given |handle| and |size|. The allocator takes ownership
-  // of the handle and closes it upon destruction, though the memory will
-  // continue to live if other processes have access to it.
-  static void CreateWithSharedMemoryHandle(const SharedMemoryHandle& handle,
-                                           size_t size);
-
-  // Sets a GlobalHistogramAllocator for globally storing histograms in
-  // a space that can be persisted or shared between processes. There is only
-  // ever one allocator for all such histograms created by a single process.
-  // This takes ownership of the object and should be called as soon as
-  // possible during startup to capture as many histograms as possible and
-  // while operating single-threaded so there are no race-conditions.
-  static void Set(std::unique_ptr<GlobalHistogramAllocator> allocator);
-
-  // Gets a pointer to the global histogram allocator. Returns null if none
-  // exists.
-  static GlobalHistogramAllocator* Get();
-
-  // This access to the persistent allocator is only for testing; it extracts
-  // the current allocator completely. This allows easy creation of histograms
-  // within persistent memory segments which can then be extracted and used in
-  // other ways.
-  static std::unique_ptr<GlobalHistogramAllocator> ReleaseForTesting();
-
-  // Stores a pathname to which the contents of this allocator should be saved
-  // in order to persist the data for a later use.
-  void SetPersistentLocation(const FilePath& location);
-
-  // Retrieves a previously set pathname to which the contents of this allocator
-  // are to be saved.
-  const FilePath& GetPersistentLocation() const;
-
-  // Writes the internal data to a previously set location. This is generally
-  // called when a process is exiting from a section of code that may not know
-  // the filesystem. The data is written in an atomic manner. The return value
-  // indicates success.
-  bool WriteToPersistentLocation();
-
-  // If there is a global metrics file being updated on disk, mark it to be
-  // deleted when the process exits.
-  void DeletePersistentLocation();
-
- private:
-  friend class StatisticsRecorder;
-
-  // Creates a new global histogram allocator.
-  explicit GlobalHistogramAllocator(
-      std::unique_ptr<PersistentMemoryAllocator> memory);
-
-  // Import new histograms from the global histogram allocator. It's possible
-  // for other processes to create histograms in the active memory segment;
-  // this adds those to the internal list of known histograms to avoid creating
-  // duplicates that would have to be merged during reporting. Every call to
-  // this method resumes from the last entry it saw; it costs nothing if
-  // nothing new has been added.
-  void ImportHistogramsToStatisticsRecorder();
-
-  // Builds a FilePath for a metrics file.
-  static FilePath MakeMetricsFilePath(const FilePath& dir, StringPiece name);
-
-  // Import always continues from where it left off, making use of a single
-  // iterator to continue the work.
-  Iterator import_iterator_;
-
-  // The location to which the data should be persisted.
-  FilePath persistent_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(GlobalHistogramAllocator);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_HISTOGRAM_PERSISTENCE_H_
diff --git a/base/metrics/persistent_histogram_storage.cc b/base/metrics/persistent_histogram_storage.cc
deleted file mode 100644
index 8f527b0..0000000
--- a/base/metrics/persistent_histogram_storage.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/persistent_histogram_storage.h"
-
-#include "base/files/file_util.h"
-#include "base/files/important_file_writer.h"
-#include "base/logging.h"
-#include "base/metrics/persistent_histogram_allocator.h"
-#include "base/metrics/persistent_memory_allocator.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/time/time.h"
-#include "build_config.h"
-
-namespace {
-
-constexpr size_t kAllocSize = 1 << 20;  // 1 MiB
-
-}  // namespace
-
-namespace base {
-
-PersistentHistogramStorage::PersistentHistogramStorage(
-    StringPiece allocator_name,
-    StorageDirManagement storage_dir_management)
-    : storage_dir_management_(storage_dir_management) {
-  DCHECK(!allocator_name.empty());
-  DCHECK(IsStringASCII(allocator_name));
-
-  GlobalHistogramAllocator::CreateWithLocalMemory(kAllocSize,
-                                                  0,  // No identifier.
-                                                  allocator_name);
-  GlobalHistogramAllocator::Get()->CreateTrackingHistograms(allocator_name);
-}
-
-PersistentHistogramStorage::~PersistentHistogramStorage() {
-  PersistentHistogramAllocator* allocator = GlobalHistogramAllocator::Get();
-  allocator->UpdateTrackingHistograms();
-
-  // TODO(chengx): Investigate making early return depend on whethere there are
-  // metrics to report at this point or not.
-  if (disabled_)
-    return;
-
-  // Stop if the storage base directory has not been properly set.
-  if (storage_base_dir_.empty()) {
-    LOG(ERROR)
-        << "Could not write \"" << allocator->Name()
-        << "\" persistent histograms to file as the storage base directory "
-           "is not properly set.";
-    return;
-  }
-
-  FilePath storage_dir = storage_base_dir_.AppendASCII(allocator->Name());
-
-  switch (storage_dir_management_) {
-    case StorageDirManagement::kCreate:
-      if (!CreateDirectory(storage_dir)) {
-        LOG(ERROR)
-            << "Could not write \"" << allocator->Name()
-            << "\" persistent histograms to file as the storage directory "
-               "cannot be created.";
-        return;
-      }
-      break;
-    case StorageDirManagement::kUseExisting:
-      if (!DirectoryExists(storage_dir)) {
-        // When the consumer of this class decides to use an existing storage
-        // directory, it should ensure the directory's existence if it's
-        // essential.
-        LOG(ERROR)
-            << "Could not write \"" << allocator->Name()
-            << "\" persistent histograms to file as the storage directory "
-               "does not exist.";
-        return;
-      }
-      break;
-  }
-
-  // Save data using the current time as the filename. The actual filename
-  // doesn't matter (so long as it ends with the correct extension) but this
-  // works as well as anything.
-  Time::Exploded exploded;
-  Time::Now().LocalExplode(&exploded);
-  const FilePath file_path =
-      storage_dir
-          .AppendASCII(StringPrintf("%04d%02d%02d%02d%02d%02d", exploded.year,
-                                    exploded.month, exploded.day_of_month,
-                                    exploded.hour, exploded.minute,
-                                    exploded.second))
-          .AddExtension(PersistentMemoryAllocator::kFileExtension);
-
-  StringPiece contents(static_cast<const char*>(allocator->data()),
-                       allocator->used());
-  if (!ImportantFileWriter::WriteFileAtomically(file_path, contents)) {
-    LOG(ERROR) << "Persistent histograms fail to write to file: "
-               << file_path.value();
-  }
-}
-
-}  // namespace base
diff --git a/base/metrics/persistent_histogram_storage.h b/base/metrics/persistent_histogram_storage.h
deleted file mode 100644
index 397236d..0000000
--- a/base/metrics/persistent_histogram_storage.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_PERSISTENT_HISTOGRAM_STORAGE_H_
-#define BASE_METRICS_PERSISTENT_HISTOGRAM_STORAGE_H_
-
-#include "base/base_export.h"
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/strings/string_piece.h"
-
-namespace base {
-
-// This class creates a fixed sized persistent memory to allow histograms to be
-// stored in it. When a PersistentHistogramStorage is destructed, histograms
-// recorded during its lifetime are persisted in the directory
-// |storage_base_dir_|/|allocator_name| (see the ctor for allocator_name).
-// Histograms are not persisted if the storage directory does not exist on
-// destruction. PersistentHistogramStorage should be instantiated as early as
-// possible in the process lifetime and should never be instantiated again.
-// Persisted histograms will eventually be reported by Chrome.
-class BASE_EXPORT PersistentHistogramStorage {
- public:
-  enum class StorageDirManagement { kCreate, kUseExisting };
-
-  // Creates a process-wide storage location for histograms that will be written
-  // to a file within a directory provided by |set_storage_base_dir()| on
-  // destruction.
-  // The |allocator_name| is used both as an internal name for the allocator,
-  // well as the leaf directory name for the file to which the histograms are
-  // persisted. The string must be ASCII.
-  // |storage_dir_management| specifies if this instance reuses an existing
-  // storage directory, or is responsible for creating one.
-  PersistentHistogramStorage(StringPiece allocator_name,
-                             StorageDirManagement storage_dir_management);
-
-  ~PersistentHistogramStorage();
-
-  // The storage directory isn't always known during initial construction so
-  // it's set separately. The last one wins if there are multiple calls to this
-  // method.
-  void set_storage_base_dir(const FilePath& storage_base_dir) {
-    storage_base_dir_ = storage_base_dir;
-  }
-
-  // Disables histogram storage.
-  void Disable() { disabled_ = true; }
-
- private:
-  // Metrics files are written into directory
-  // |storage_base_dir_|/|allocator_name| (see the ctor for allocator_name).
-  FilePath storage_base_dir_;
-
-  // The setting of the storage directory management.
-  const StorageDirManagement storage_dir_management_;
-
-  // A flag indicating if histogram storage is disabled. It starts with false,
-  // but can be set to true by the caller who decides to throw away its
-  // histogram data.
-  bool disabled_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(PersistentHistogramStorage);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_PERSISTENT_HISTOGRAM_STORAGE_H_
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
deleted file mode 100644
index 7d9c03d..0000000
--- a/base/metrics/persistent_memory_allocator.cc
+++ /dev/null
@@ -1,1204 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/persistent_memory_allocator.h"
-
-#include <assert.h>
-#include <algorithm>
-
-#if defined(OS_WIN)
-#include <windows.h>
-#include "winbase.h"
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
-#include <sys/mman.h>
-#endif
-
-#include "base/files/memory_mapped_file.h"
-#include "base/logging.h"
-#include "base/memory/shared_memory.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/sys_info.h"
-#include "base/threading/thread_restrictions.h"
-#include "build_config.h"
-
-namespace {
-
-// Limit of memory segment size. It has to fit in an unsigned 32-bit number
-// and should be a power of 2 in order to accomodate almost any page size.
-const uint32_t kSegmentMaxSize = 1 << 30;  // 1 GiB
-
-// A constant (random) value placed in the shared metadata to identify
-// an already initialized memory segment.
-const uint32_t kGlobalCookie = 0x408305DC;
-
-// The current version of the metadata. If updates are made that change
-// the metadata, the version number can be queried to operate in a backward-
-// compatible manner until the memory segment is completely re-initalized.
-const uint32_t kGlobalVersion = 2;
-
-// Constant values placed in the block headers to indicate its state.
-const uint32_t kBlockCookieFree = 0;
-const uint32_t kBlockCookieQueue = 1;
-const uint32_t kBlockCookieWasted = (uint32_t)-1;
-const uint32_t kBlockCookieAllocated = 0xC8799269;
-
-// TODO(bcwhite): When acceptable, consider moving flags to std::atomic<char>
-// types rather than combined bitfield.
-
-// Flags stored in the flags_ field of the SharedMetadata structure below.
-enum : int {
-  kFlagCorrupt = 1 << 0,
-  kFlagFull    = 1 << 1
-};
-
-// Errors that are logged in "errors" histogram.
-enum AllocatorError : int {
-  kMemoryIsCorrupt = 1,
-};
-
-bool CheckFlag(const volatile std::atomic<uint32_t>* flags, int flag) {
-  uint32_t loaded_flags = flags->load(std::memory_order_relaxed);
-  return (loaded_flags & flag) != 0;
-}
-
-void SetFlag(volatile std::atomic<uint32_t>* flags, int flag) {
-  uint32_t loaded_flags = flags->load(std::memory_order_relaxed);
-  for (;;) {
-    uint32_t new_flags = (loaded_flags & ~flag) | flag;
-    // In the failue case, actual "flags" value stored in loaded_flags.
-    // These access are "relaxed" because they are completely independent
-    // of all other values.
-    if (flags->compare_exchange_weak(loaded_flags, new_flags,
-                                     std::memory_order_relaxed,
-                                     std::memory_order_relaxed)) {
-      break;
-    }
-  }
-}
-
-}  // namespace
-
-namespace base {
-
-// All allocations and data-structures must be aligned to this byte boundary.
-// Alignment as large as the physical bus between CPU and RAM is _required_
-// for some architectures, is simply more efficient on other CPUs, and
-// generally a Good Idea(tm) for all platforms as it reduces/eliminates the
-// chance that a type will span cache lines. Alignment mustn't be less
-// than 8 to ensure proper alignment for all types. The rest is a balance
-// between reducing spans across multiple cache lines and wasted space spent
-// padding out allocations. An alignment of 16 would ensure that the block
-// header structure always sits in a single cache line. An average of about
-// 1/2 this value will be wasted with every allocation.
-const uint32_t PersistentMemoryAllocator::kAllocAlignment = 8;
-
-// The block-header is placed at the top of every allocation within the
-// segment to describe the data that follows it.
-struct PersistentMemoryAllocator::BlockHeader {
-  uint32_t size;       // Number of bytes in this block, including header.
-  uint32_t cookie;     // Constant value indicating completed allocation.
-  std::atomic<uint32_t> type_id;  // Arbitrary number indicating data type.
-  std::atomic<uint32_t> next;     // Pointer to the next block when iterating.
-};
-
-// The shared metadata exists once at the top of the memory segment to
-// describe the state of the allocator to all processes. The size of this
-// structure must be a multiple of 64-bits to ensure compatibility between
-// architectures.
-struct PersistentMemoryAllocator::SharedMetadata {
-  uint32_t cookie;     // Some value that indicates complete initialization.
-  uint32_t size;       // Total size of memory segment.
-  uint32_t page_size;  // Paging size within memory segment.
-  uint32_t version;    // Version code so upgrades don't break.
-  uint64_t id;         // Arbitrary ID number given by creator.
-  uint32_t name;       // Reference to stored name string.
-  uint32_t padding1;   // Pad-out read-only data to 64-bit alignment.
-
-  // Above is read-only after first construction. Below may be changed and
-  // so must be marked "volatile" to provide correct inter-process behavior.
-
-  // State of the memory, plus some padding to keep alignment.
-  volatile std::atomic<uint8_t> memory_state;  // MemoryState enum values.
-  uint8_t padding2[3];
-
-  // Bitfield of information flags. Access to this should be done through
-  // the CheckFlag() and SetFlag() methods defined above.
-  volatile std::atomic<uint32_t> flags;
-
-  // Offset/reference to first free space in segment.
-  volatile std::atomic<uint32_t> freeptr;
-
-  // The "iterable" queue is an M&S Queue as described here, append-only:
-  // https://www.research.ibm.com/people/m/michael/podc-1996.pdf
-  // |queue| needs to be 64-bit aligned and is itself a multiple of 64 bits.
-  volatile std::atomic<uint32_t> tailptr;  // Last block of iteration queue.
-  volatile BlockHeader queue;   // Empty block for linked-list head/tail.
-};
-
-// The "queue" block header is used to detect "last node" so that zero/null
-// can be used to indicate that it hasn't been added at all. It is part of
-// the SharedMetadata structure which itself is always located at offset zero.
-const PersistentMemoryAllocator::Reference
-    PersistentMemoryAllocator::kReferenceQueue =
-        offsetof(SharedMetadata, queue);
-
-const base::FilePath::CharType PersistentMemoryAllocator::kFileExtension[] =
-    FILE_PATH_LITERAL(".pma");
-
-
-PersistentMemoryAllocator::Iterator::Iterator(
-    const PersistentMemoryAllocator* allocator)
-    : allocator_(allocator), last_record_(kReferenceQueue), record_count_(0) {}
-
-PersistentMemoryAllocator::Iterator::Iterator(
-    const PersistentMemoryAllocator* allocator,
-    Reference starting_after)
-    : allocator_(allocator), last_record_(0), record_count_(0) {
-  Reset(starting_after);
-}
-
-void PersistentMemoryAllocator::Iterator::Reset() {
-  last_record_.store(kReferenceQueue, std::memory_order_relaxed);
-  record_count_.store(0, std::memory_order_relaxed);
-}
-
-void PersistentMemoryAllocator::Iterator::Reset(Reference starting_after) {
-  if (starting_after == 0) {
-    Reset();
-    return;
-  }
-
-  last_record_.store(starting_after, std::memory_order_relaxed);
-  record_count_.store(0, std::memory_order_relaxed);
-
-  // Ensure that the starting point is a valid, iterable block (meaning it can
-  // be read and has a non-zero "next" pointer).
-  const volatile BlockHeader* block =
-      allocator_->GetBlock(starting_after, 0, 0, false, false);
-  if (!block || block->next.load(std::memory_order_relaxed) == 0) {
-    NOTREACHED();
-    last_record_.store(kReferenceQueue, std::memory_order_release);
-  }
-}
-
-PersistentMemoryAllocator::Reference
-PersistentMemoryAllocator::Iterator::GetLast() {
-  Reference last = last_record_.load(std::memory_order_relaxed);
-  if (last == kReferenceQueue)
-    return kReferenceNull;
-  return last;
-}
-
-PersistentMemoryAllocator::Reference
-PersistentMemoryAllocator::Iterator::GetNext(uint32_t* type_return) {
-  // Make a copy of the existing count of found-records, acquiring all changes
-  // made to the allocator, notably "freeptr" (see comment in loop for why
-  // the load of that value cannot be moved above here) that occurred during
-  // any previous runs of this method, including those by parallel threads
-  // that interrupted it. It pairs with the Release at the end of this method.
-  //
-  // Otherwise, if the compiler were to arrange the two loads such that
-  // "count" was fetched _after_ "freeptr" then it would be possible for
-  // this thread to be interrupted between them and other threads perform
-  // multiple allocations, make-iterables, and iterations (with the included
-  // increment of |record_count_|) culminating in the check at the bottom
-  // mistakenly determining that a loop exists. Isn't this stuff fun?
-  uint32_t count = record_count_.load(std::memory_order_acquire);
-
-  Reference last = last_record_.load(std::memory_order_acquire);
-  Reference next;
-  while (true) {
-    const volatile BlockHeader* block =
-        allocator_->GetBlock(last, 0, 0, true, false);
-    if (!block)  // Invalid iterator state.
-      return kReferenceNull;
-
-    // The compiler and CPU can freely reorder all memory accesses on which
-    // there are no dependencies. It could, for example, move the load of
-    // "freeptr" to above this point because there are no explicit dependencies
-    // between it and "next". If it did, however, then another block could
-    // be queued after that but before the following load meaning there is
-    // one more queued block than the future "detect loop by having more
-    // blocks that could fit before freeptr" will allow.
-    //
-    // By "acquiring" the "next" value here, it's synchronized to the enqueue
-    // of the node which in turn is synchronized to the allocation (which sets
-    // freeptr). Thus, the scenario above cannot happen.
-    next = block->next.load(std::memory_order_acquire);
-    if (next == kReferenceQueue)  // No next allocation in queue.
-      return kReferenceNull;
-    block = allocator_->GetBlock(next, 0, 0, false, false);
-    if (!block) {  // Memory is corrupt.
-      allocator_->SetCorrupt();
-      return kReferenceNull;
-    }
-
-    // Update the "last_record" pointer to be the reference being returned.
-    // If it fails then another thread has already iterated past it so loop
-    // again. Failing will also load the existing value into "last" so there
-    // is no need to do another such load when the while-loop restarts. A
-    // "strong" compare-exchange is used because failing unnecessarily would
-    // mean repeating some fairly costly validations above.
-    if (last_record_.compare_exchange_strong(
-            last, next, std::memory_order_acq_rel, std::memory_order_acquire)) {
-      *type_return = block->type_id.load(std::memory_order_relaxed);
-      break;
-    }
-  }
-
-  // Memory corruption could cause a loop in the list. Such must be detected
-  // so as to not cause an infinite loop in the caller. This is done by simply
-  // making sure it doesn't iterate more times than the absolute maximum
-  // number of allocations that could have been made. Callers are likely
-  // to loop multiple times before it is detected but at least it stops.
-  const uint32_t freeptr = std::min(
-      allocator_->shared_meta()->freeptr.load(std::memory_order_relaxed),
-      allocator_->mem_size_);
-  const uint32_t max_records =
-      freeptr / (sizeof(BlockHeader) + kAllocAlignment);
-  if (count > max_records) {
-    allocator_->SetCorrupt();
-    return kReferenceNull;
-  }
-
-  // Increment the count and release the changes made above. It pairs with
-  // the Acquire at the top of this method. Note that this operation is not
-  // strictly synchonized with fetching of the object to return, which would
-  // have to be done inside the loop and is somewhat complicated to achieve.
-  // It does not matter if it falls behind temporarily so long as it never
-  // gets ahead.
-  record_count_.fetch_add(1, std::memory_order_release);
-  return next;
-}
-
-PersistentMemoryAllocator::Reference
-PersistentMemoryAllocator::Iterator::GetNextOfType(uint32_t type_match) {
-  Reference ref;
-  uint32_t type_found;
-  while ((ref = GetNext(&type_found)) != 0) {
-    if (type_found == type_match)
-      return ref;
-  }
-  return kReferenceNull;
-}
-
-
-// static
-bool PersistentMemoryAllocator::IsMemoryAcceptable(const void* base,
-                                                   size_t size,
-                                                   size_t page_size,
-                                                   bool readonly) {
-  return ((base && reinterpret_cast<uintptr_t>(base) % kAllocAlignment == 0) &&
-          (size >= sizeof(SharedMetadata) && size <= kSegmentMaxSize) &&
-          (size % kAllocAlignment == 0 || readonly) &&
-          (page_size == 0 || size % page_size == 0 || readonly));
-}
-
-PersistentMemoryAllocator::PersistentMemoryAllocator(void* base,
-                                                     size_t size,
-                                                     size_t page_size,
-                                                     uint64_t id,
-                                                     base::StringPiece name,
-                                                     bool readonly)
-    : PersistentMemoryAllocator(Memory(base, MEM_EXTERNAL),
-                                size,
-                                page_size,
-                                id,
-                                name,
-                                readonly) {}
-
-PersistentMemoryAllocator::PersistentMemoryAllocator(Memory memory,
-                                                     size_t size,
-                                                     size_t page_size,
-                                                     uint64_t id,
-                                                     base::StringPiece name,
-                                                     bool readonly)
-    : mem_base_(static_cast<char*>(memory.base)),
-      mem_type_(memory.type),
-      mem_size_(static_cast<uint32_t>(size)),
-      mem_page_(static_cast<uint32_t>((page_size ? page_size : size))),
-#if defined(OS_NACL)
-      vm_page_size_(4096U),  // SysInfo is not built for NACL.
-#else
-      vm_page_size_(SysInfo::VMAllocationGranularity()),
-#endif
-      readonly_(readonly),
-      corrupt_(0),
-      allocs_histogram_(nullptr),
-      used_histogram_(nullptr),
-      errors_histogram_(nullptr) {
-  // These asserts ensure that the structures are 32/64-bit agnostic and meet
-  // all the requirements of use within the allocator. They access private
-  // definitions and so cannot be moved to the global scope.
-  static_assert(sizeof(PersistentMemoryAllocator::BlockHeader) == 16,
-                "struct is not portable across different natural word widths");
-  static_assert(sizeof(PersistentMemoryAllocator::SharedMetadata) == 64,
-                "struct is not portable across different natural word widths");
-
-  static_assert(sizeof(BlockHeader) % kAllocAlignment == 0,
-                "BlockHeader is not a multiple of kAllocAlignment");
-  static_assert(sizeof(SharedMetadata) % kAllocAlignment == 0,
-                "SharedMetadata is not a multiple of kAllocAlignment");
-  static_assert(kReferenceQueue % kAllocAlignment == 0,
-                "\"queue\" is not aligned properly; must be at end of struct");
-
-  // Ensure that memory segment is of acceptable size.
-  CHECK(IsMemoryAcceptable(memory.base, size, page_size, readonly));
-
-  // These atomics operate inter-process and so must be lock-free. The local
-  // casts are to make sure it can be evaluated at compile time to a constant.
-  CHECK(((SharedMetadata*)nullptr)->freeptr.is_lock_free());
-  CHECK(((SharedMetadata*)nullptr)->flags.is_lock_free());
-  CHECK(((BlockHeader*)nullptr)->next.is_lock_free());
-  CHECK(corrupt_.is_lock_free());
-
-  if (shared_meta()->cookie != kGlobalCookie) {
-    if (readonly) {
-      SetCorrupt();
-      return;
-    }
-
-    // This block is only executed when a completely new memory segment is
-    // being initialized. It's unshared and single-threaded...
-    volatile BlockHeader* const first_block =
-        reinterpret_cast<volatile BlockHeader*>(mem_base_ +
-                                                sizeof(SharedMetadata));
-    if (shared_meta()->cookie != 0 ||
-        shared_meta()->size != 0 ||
-        shared_meta()->version != 0 ||
-        shared_meta()->freeptr.load(std::memory_order_relaxed) != 0 ||
-        shared_meta()->flags.load(std::memory_order_relaxed) != 0 ||
-        shared_meta()->id != 0 ||
-        shared_meta()->name != 0 ||
-        shared_meta()->tailptr != 0 ||
-        shared_meta()->queue.cookie != 0 ||
-        shared_meta()->queue.next.load(std::memory_order_relaxed) != 0 ||
-        first_block->size != 0 ||
-        first_block->cookie != 0 ||
-        first_block->type_id.load(std::memory_order_relaxed) != 0 ||
-        first_block->next != 0) {
-      // ...or something malicious has been playing with the metadata.
-      SetCorrupt();
-    }
-
-    // This is still safe to do even if corruption has been detected.
-    shared_meta()->cookie = kGlobalCookie;
-    shared_meta()->size = mem_size_;
-    shared_meta()->page_size = mem_page_;
-    shared_meta()->version = kGlobalVersion;
-    shared_meta()->id = id;
-    shared_meta()->freeptr.store(sizeof(SharedMetadata),
-                                 std::memory_order_release);
-
-    // Set up the queue of iterable allocations.
-    shared_meta()->queue.size = sizeof(BlockHeader);
-    shared_meta()->queue.cookie = kBlockCookieQueue;
-    shared_meta()->queue.next.store(kReferenceQueue, std::memory_order_release);
-    shared_meta()->tailptr.store(kReferenceQueue, std::memory_order_release);
-
-    // Allocate space for the name so other processes can learn it.
-    if (!name.empty()) {
-      const size_t name_length = name.length() + 1;
-      shared_meta()->name = Allocate(name_length, 0);
-      char* name_cstr = GetAsArray<char>(shared_meta()->name, 0, name_length);
-      if (name_cstr)
-        memcpy(name_cstr, name.data(), name.length());
-    }
-
-    shared_meta()->memory_state.store(MEMORY_INITIALIZED,
-                                      std::memory_order_release);
-  } else {
-    if (shared_meta()->size == 0 || shared_meta()->version != kGlobalVersion ||
-        shared_meta()->freeptr.load(std::memory_order_relaxed) == 0 ||
-        shared_meta()->tailptr == 0 || shared_meta()->queue.cookie == 0 ||
-        shared_meta()->queue.next.load(std::memory_order_relaxed) == 0) {
-      SetCorrupt();
-    }
-    if (!readonly) {
-      // The allocator is attaching to a previously initialized segment of
-      // memory. If the initialization parameters differ, make the best of it
-      // by reducing the local construction parameters to match those of
-      // the actual memory area. This ensures that the local object never
-      // tries to write outside of the original bounds.
-      // Because the fields are const to ensure that no code other than the
-      // constructor makes changes to them as well as to give optimization
-      // hints to the compiler, it's necessary to const-cast them for changes
-      // here.
-      if (shared_meta()->size < mem_size_)
-        *const_cast<uint32_t*>(&mem_size_) = shared_meta()->size;
-      if (shared_meta()->page_size < mem_page_)
-        *const_cast<uint32_t*>(&mem_page_) = shared_meta()->page_size;
-
-      // Ensure that settings are still valid after the above adjustments.
-      if (!IsMemoryAcceptable(memory.base, mem_size_, mem_page_, readonly))
-        SetCorrupt();
-    }
-  }
-}
-
-PersistentMemoryAllocator::~PersistentMemoryAllocator() {
-  // It's strictly forbidden to do any memory access here in case there is
-  // some issue with the underlying memory segment. The "Local" allocator
-  // makes use of this to allow deletion of the segment on the heap from
-  // within its destructor.
-}
-
-uint64_t PersistentMemoryAllocator::Id() const {
-  return shared_meta()->id;
-}
-
-const char* PersistentMemoryAllocator::Name() const {
-  Reference name_ref = shared_meta()->name;
-  const char* name_cstr =
-      GetAsArray<char>(name_ref, 0, PersistentMemoryAllocator::kSizeAny);
-  if (!name_cstr)
-    return "";
-
-  size_t name_length = GetAllocSize(name_ref);
-  if (name_cstr[name_length - 1] != '\0') {
-    NOTREACHED();
-    SetCorrupt();
-    return "";
-  }
-
-  return name_cstr;
-}
-
-void PersistentMemoryAllocator::CreateTrackingHistograms(
-    base::StringPiece name) {
-  if (name.empty() || readonly_)
-    return;
-  std::string name_string = name.as_string();
-
-#if 0
-  // This histogram wasn't being used so has been disabled. It is left here
-  // in case development of a new use of the allocator could benefit from
-  // recording (temporarily and locally) the allocation sizes.
-  DCHECK(!allocs_histogram_);
-  allocs_histogram_ = Histogram::FactoryGet(
-      "UMA.PersistentAllocator." + name_string + ".Allocs", 1, 10000, 50,
-      HistogramBase::kUmaTargetedHistogramFlag);
-#endif
-
-  DCHECK(!used_histogram_);
-  used_histogram_ = LinearHistogram::FactoryGet(
-      "UMA.PersistentAllocator." + name_string + ".UsedPct", 1, 101, 21,
-      HistogramBase::kUmaTargetedHistogramFlag);
-
-  DCHECK(!errors_histogram_);
-  errors_histogram_ = SparseHistogram::FactoryGet(
-      "UMA.PersistentAllocator." + name_string + ".Errors",
-      HistogramBase::kUmaTargetedHistogramFlag);
-}
-
-void PersistentMemoryAllocator::Flush(bool sync) {
-  FlushPartial(used(), sync);
-}
-
-void PersistentMemoryAllocator::SetMemoryState(uint8_t memory_state) {
-  shared_meta()->memory_state.store(memory_state, std::memory_order_relaxed);
-  FlushPartial(sizeof(SharedMetadata), false);
-}
-
-uint8_t PersistentMemoryAllocator::GetMemoryState() const {
-  return shared_meta()->memory_state.load(std::memory_order_relaxed);
-}
-
-size_t PersistentMemoryAllocator::used() const {
-  return std::min(shared_meta()->freeptr.load(std::memory_order_relaxed),
-                  mem_size_);
-}
-
-PersistentMemoryAllocator::Reference PersistentMemoryAllocator::GetAsReference(
-    const void* memory,
-    uint32_t type_id) const {
-  uintptr_t address = reinterpret_cast<uintptr_t>(memory);
-  if (address < reinterpret_cast<uintptr_t>(mem_base_))
-    return kReferenceNull;
-
-  uintptr_t offset = address - reinterpret_cast<uintptr_t>(mem_base_);
-  if (offset >= mem_size_ || offset < sizeof(BlockHeader))
-    return kReferenceNull;
-
-  Reference ref = static_cast<Reference>(offset) - sizeof(BlockHeader);
-  if (!GetBlockData(ref, type_id, kSizeAny))
-    return kReferenceNull;
-
-  return ref;
-}
-
-size_t PersistentMemoryAllocator::GetAllocSize(Reference ref) const {
-  const volatile BlockHeader* const block = GetBlock(ref, 0, 0, false, false);
-  if (!block)
-    return 0;
-  uint32_t size = block->size;
-  // Header was verified by GetBlock() but a malicious actor could change
-  // the value between there and here. Check it again.
-  if (size <= sizeof(BlockHeader) || ref + size > mem_size_) {
-    SetCorrupt();
-    return 0;
-  }
-  return size - sizeof(BlockHeader);
-}
-
-uint32_t PersistentMemoryAllocator::GetType(Reference ref) const {
-  const volatile BlockHeader* const block = GetBlock(ref, 0, 0, false, false);
-  if (!block)
-    return 0;
-  return block->type_id.load(std::memory_order_relaxed);
-}
-
-bool PersistentMemoryAllocator::ChangeType(Reference ref,
-                                           uint32_t to_type_id,
-                                           uint32_t from_type_id,
-                                           bool clear) {
-  DCHECK(!readonly_);
-  volatile BlockHeader* const block = GetBlock(ref, 0, 0, false, false);
-  if (!block)
-    return false;
-
-  // "Strong" exchanges are used below because there is no loop that can retry
-  // in the wake of spurious failures possible with "weak" exchanges. It is,
-  // in aggregate, an "acquire-release" operation so no memory accesses can be
-  // reordered either before or after this method (since changes based on type
-  // could happen on either side).
-
-  if (clear) {
-    // If clearing the memory, first change it to the "transitioning" type so
-    // there can be no confusion by other threads. After the memory is cleared,
-    // it can be changed to its final type.
-    if (!block->type_id.compare_exchange_strong(
-            from_type_id, kTypeIdTransitioning, std::memory_order_acquire,
-            std::memory_order_acquire)) {
-      // Existing type wasn't what was expected: fail (with no changes)
-      return false;
-    }
-
-    // Clear the memory in an atomic manner. Using "release" stores force
-    // every write to be done after the ones before it. This is better than
-    // using memset because (a) it supports "volatile" and (b) it creates a
-    // reliable pattern upon which other threads may rely.
-    volatile std::atomic<int>* data =
-        reinterpret_cast<volatile std::atomic<int>*>(
-            reinterpret_cast<volatile char*>(block) + sizeof(BlockHeader));
-    const uint32_t words = (block->size - sizeof(BlockHeader)) / sizeof(int);
-    DCHECK_EQ(0U, (block->size - sizeof(BlockHeader)) % sizeof(int));
-    for (uint32_t i = 0; i < words; ++i) {
-      data->store(0, std::memory_order_release);
-      ++data;
-    }
-
-    // If the destination type is "transitioning" then skip the final exchange.
-    if (to_type_id == kTypeIdTransitioning)
-      return true;
-
-    // Finish the change to the desired type.
-    from_type_id = kTypeIdTransitioning;  // Exchange needs modifiable original.
-    bool success = block->type_id.compare_exchange_strong(
-        from_type_id, to_type_id, std::memory_order_release,
-        std::memory_order_relaxed);
-    DCHECK(success);  // Should never fail.
-    return success;
-  }
-
-  // One step change to the new type. Will return false if the existing value
-  // doesn't match what is expected.
-  return block->type_id.compare_exchange_strong(from_type_id, to_type_id,
-                                                std::memory_order_acq_rel,
-                                                std::memory_order_acquire);
-}
-
-PersistentMemoryAllocator::Reference PersistentMemoryAllocator::Allocate(
-    size_t req_size,
-    uint32_t type_id) {
-  Reference ref = AllocateImpl(req_size, type_id);
-  if (ref) {
-    // Success: Record this allocation in usage stats (if active).
-    if (allocs_histogram_)
-      allocs_histogram_->Add(static_cast<HistogramBase::Sample>(req_size));
-  } else {
-    // Failure: Record an allocation of zero for tracking.
-    if (allocs_histogram_)
-      allocs_histogram_->Add(0);
-  }
-  return ref;
-}
-
-PersistentMemoryAllocator::Reference PersistentMemoryAllocator::AllocateImpl(
-    size_t req_size,
-    uint32_t type_id) {
-  DCHECK(!readonly_);
-
-  // Validate req_size to ensure it won't overflow when used as 32-bit value.
-  if (req_size > kSegmentMaxSize - sizeof(BlockHeader)) {
-    NOTREACHED();
-    return kReferenceNull;
-  }
-
-  // Round up the requested size, plus header, to the next allocation alignment.
-  uint32_t size = static_cast<uint32_t>(req_size + sizeof(BlockHeader));
-  size = (size + (kAllocAlignment - 1)) & ~(kAllocAlignment - 1);
-  if (size <= sizeof(BlockHeader) || size > mem_page_) {
-    NOTREACHED();
-    return kReferenceNull;
-  }
-
-  // Get the current start of unallocated memory. Other threads may
-  // update this at any time and cause us to retry these operations.
-  // This value should be treated as "const" to avoid confusion through
-  // the code below but recognize that any failed compare-exchange operation
-  // involving it will cause it to be loaded with a more recent value. The
-  // code should either exit or restart the loop in that case.
-  /* const */ uint32_t freeptr =
-      shared_meta()->freeptr.load(std::memory_order_acquire);
-
-  // Allocation is lockless so we do all our caculation and then, if saving
-  // indicates a change has occurred since we started, scrap everything and
-  // start over.
-  for (;;) {
-    if (IsCorrupt())
-      return kReferenceNull;
-
-    if (freeptr + size > mem_size_) {
-      SetFlag(&shared_meta()->flags, kFlagFull);
-      return kReferenceNull;
-    }
-
-    // Get pointer to the "free" block. If something has been allocated since
-    // the load of freeptr above, it is still safe as nothing will be written
-    // to that location until after the compare-exchange below.
-    volatile BlockHeader* const block = GetBlock(freeptr, 0, 0, false, true);
-    if (!block) {
-      SetCorrupt();
-      return kReferenceNull;
-    }
-
-    // An allocation cannot cross page boundaries. If it would, create a
-    // "wasted" block and begin again at the top of the next page. This
-    // area could just be left empty but we fill in the block header just
-    // for completeness sake.
-    const uint32_t page_free = mem_page_ - freeptr % mem_page_;
-    if (size > page_free) {
-      if (page_free <= sizeof(BlockHeader)) {
-        SetCorrupt();
-        return kReferenceNull;
-      }
-      const uint32_t new_freeptr = freeptr + page_free;
-      if (shared_meta()->freeptr.compare_exchange_strong(
-              freeptr, new_freeptr, std::memory_order_acq_rel,
-              std::memory_order_acquire)) {
-        block->size = page_free;
-        block->cookie = kBlockCookieWasted;
-      }
-      continue;
-    }
-
-    // Don't leave a slice at the end of a page too small for anything. This
-    // can result in an allocation up to two alignment-sizes greater than the
-    // minimum required by requested-size + header + alignment.
-    if (page_free - size < sizeof(BlockHeader) + kAllocAlignment)
-      size = page_free;
-
-    const uint32_t new_freeptr = freeptr + size;
-    if (new_freeptr > mem_size_) {
-      SetCorrupt();
-      return kReferenceNull;
-    }
-
-    // Save our work. Try again if another thread has completed an allocation
-    // while we were processing. A "weak" exchange would be permissable here
-    // because the code will just loop and try again but the above processing
-    // is significant so make the extra effort of a "strong" exchange.
-    if (!shared_meta()->freeptr.compare_exchange_strong(
-            freeptr, new_freeptr, std::memory_order_acq_rel,
-            std::memory_order_acquire)) {
-      continue;
-    }
-
-    // Given that all memory was zeroed before ever being given to an instance
-    // of this class and given that we only allocate in a monotomic fashion
-    // going forward, it must be that the newly allocated block is completely
-    // full of zeros. If we find anything in the block header that is NOT a
-    // zero then something must have previously run amuck through memory,
-    // writing beyond the allocated space and into unallocated space.
-    if (block->size != 0 ||
-        block->cookie != kBlockCookieFree ||
-        block->type_id.load(std::memory_order_relaxed) != 0 ||
-        block->next.load(std::memory_order_relaxed) != 0) {
-      SetCorrupt();
-      return kReferenceNull;
-    }
-
-    // Make sure the memory exists by writing to the first byte of every memory
-    // page it touches beyond the one containing the block header itself.
-    // As the underlying storage is often memory mapped from disk or shared
-    // space, sometimes things go wrong and those address don't actually exist
-    // leading to a SIGBUS (or Windows equivalent) at some arbitrary location
-    // in the code. This should concentrate all those failures into this
-    // location for easy tracking and, eventually, proper handling.
-    volatile char* mem_end = reinterpret_cast<volatile char*>(block) + size;
-    volatile char* mem_begin = reinterpret_cast<volatile char*>(
-        (reinterpret_cast<uintptr_t>(block) + sizeof(BlockHeader) +
-         (vm_page_size_ - 1)) &
-        ~static_cast<uintptr_t>(vm_page_size_ - 1));
-    for (volatile char* memory = mem_begin; memory < mem_end;
-         memory += vm_page_size_) {
-      // It's required that a memory segment start as all zeros and thus the
-      // newly allocated block is all zeros at this point. Thus, writing a
-      // zero to it allows testing that the memory exists without actually
-      // changing its contents. The compiler doesn't know about the requirement
-      // and so cannot optimize-away these writes.
-      *memory = 0;
-    }
-
-    // Load information into the block header. There is no "release" of the
-    // data here because this memory can, currently, be seen only by the thread
-    // performing the allocation. When it comes time to share this, the thread
-    // will call MakeIterable() which does the release operation.
-    block->size = size;
-    block->cookie = kBlockCookieAllocated;
-    block->type_id.store(type_id, std::memory_order_relaxed);
-    return freeptr;
-  }
-}
-
-void PersistentMemoryAllocator::GetMemoryInfo(MemoryInfo* meminfo) const {
-  uint32_t remaining = std::max(
-      mem_size_ - shared_meta()->freeptr.load(std::memory_order_relaxed),
-      (uint32_t)sizeof(BlockHeader));
-  meminfo->total = mem_size_;
-  meminfo->free = remaining - sizeof(BlockHeader);
-}
-
-void PersistentMemoryAllocator::MakeIterable(Reference ref) {
-  DCHECK(!readonly_);
-  if (IsCorrupt())
-    return;
-  volatile BlockHeader* block = GetBlock(ref, 0, 0, false, false);
-  if (!block)  // invalid reference
-    return;
-  if (block->next.load(std::memory_order_acquire) != 0)  // Already iterable.
-    return;
-  block->next.store(kReferenceQueue, std::memory_order_release);  // New tail.
-
-  // Try to add this block to the tail of the queue. May take multiple tries.
-  // If so, tail will be automatically updated with a more recent value during
-  // compare-exchange operations.
-  uint32_t tail = shared_meta()->tailptr.load(std::memory_order_acquire);
-  for (;;) {
-    // Acquire the current tail-pointer released by previous call to this
-    // method and validate it.
-    block = GetBlock(tail, 0, 0, true, false);
-    if (!block) {
-      SetCorrupt();
-      return;
-    }
-
-    // Try to insert the block at the tail of the queue. The tail node always
-    // has an existing value of kReferenceQueue; if that is somehow not the
-    // existing value then another thread has acted in the meantime. A "strong"
-    // exchange is necessary so the "else" block does not get executed when
-    // that is not actually the case (which can happen with a "weak" exchange).
-    uint32_t next = kReferenceQueue;  // Will get replaced with existing value.
-    if (block->next.compare_exchange_strong(next, ref,
-                                            std::memory_order_acq_rel,
-                                            std::memory_order_acquire)) {
-      // Update the tail pointer to the new offset. If the "else" clause did
-      // not exist, then this could be a simple Release_Store to set the new
-      // value but because it does, it's possible that other threads could add
-      // one or more nodes at the tail before reaching this point. We don't
-      // have to check the return value because it either operates correctly
-      // or the exact same operation has already been done (by the "else"
-      // clause) on some other thread.
-      shared_meta()->tailptr.compare_exchange_strong(tail, ref,
-                                                     std::memory_order_release,
-                                                     std::memory_order_relaxed);
-      return;
-    } else {
-      // In the unlikely case that a thread crashed or was killed between the
-      // update of "next" and the update of "tailptr", it is necessary to
-      // perform the operation that would have been done. There's no explicit
-      // check for crash/kill which means that this operation may also happen
-      // even when the other thread is in perfect working order which is what
-      // necessitates the CompareAndSwap above.
-      shared_meta()->tailptr.compare_exchange_strong(tail, next,
-                                                     std::memory_order_acq_rel,
-                                                     std::memory_order_acquire);
-    }
-  }
-}
-
-// The "corrupted" state is held both locally and globally (shared). The
-// shared flag can't be trusted since a malicious actor could overwrite it.
-// Because corruption can be detected during read-only operations such as
-// iteration, this method may be called by other "const" methods. In this
-// case, it's safe to discard the constness and modify the local flag and
-// maybe even the shared flag if the underlying data isn't actually read-only.
-void PersistentMemoryAllocator::SetCorrupt() const {
-  if (!corrupt_.load(std::memory_order_relaxed) &&
-      !CheckFlag(
-          const_cast<volatile std::atomic<uint32_t>*>(&shared_meta()->flags),
-          kFlagCorrupt)) {
-    LOG(ERROR) << "Corruption detected in shared-memory segment.";
-    RecordError(kMemoryIsCorrupt);
-  }
-
-  corrupt_.store(true, std::memory_order_relaxed);
-  if (!readonly_) {
-    SetFlag(const_cast<volatile std::atomic<uint32_t>*>(&shared_meta()->flags),
-            kFlagCorrupt);
-  }
-}
-
-bool PersistentMemoryAllocator::IsCorrupt() const {
-  if (corrupt_.load(std::memory_order_relaxed) ||
-      CheckFlag(&shared_meta()->flags, kFlagCorrupt)) {
-    SetCorrupt();  // Make sure all indicators are set.
-    return true;
-  }
-  return false;
-}
-
-bool PersistentMemoryAllocator::IsFull() const {
-  return CheckFlag(&shared_meta()->flags, kFlagFull);
-}
-
-// Dereference a block |ref| and ensure that it's valid for the desired
-// |type_id| and |size|. |special| indicates that we may try to access block
-// headers not available to callers but still accessed by this module. By
-// having internal dereferences go through this same function, the allocator
-// is hardened against corruption.
-const volatile PersistentMemoryAllocator::BlockHeader*
-PersistentMemoryAllocator::GetBlock(Reference ref, uint32_t type_id,
-                                    uint32_t size, bool queue_ok,
-                                    bool free_ok) const {
-  // Handle special cases.
-  if (ref == kReferenceQueue && queue_ok)
-    return reinterpret_cast<const volatile BlockHeader*>(mem_base_ + ref);
-
-  // Validation of parameters.
-  if (ref < sizeof(SharedMetadata))
-    return nullptr;
-  if (ref % kAllocAlignment != 0)
-    return nullptr;
-  size += sizeof(BlockHeader);
-  if (ref + size > mem_size_)
-    return nullptr;
-
-  // Validation of referenced block-header.
-  if (!free_ok) {
-    const volatile BlockHeader* const block =
-        reinterpret_cast<volatile BlockHeader*>(mem_base_ + ref);
-    if (block->cookie != kBlockCookieAllocated)
-      return nullptr;
-    if (block->size < size)
-      return nullptr;
-    if (ref + block->size > mem_size_)
-      return nullptr;
-    if (type_id != 0 &&
-        block->type_id.load(std::memory_order_relaxed) != type_id) {
-      return nullptr;
-    }
-  }
-
-  // Return pointer to block data.
-  return reinterpret_cast<const volatile BlockHeader*>(mem_base_ + ref);
-}
-
-void PersistentMemoryAllocator::FlushPartial(size_t length, bool sync) {
-  // Generally there is nothing to do as every write is done through volatile
-  // memory with atomic instructions to guarantee consistency. This (virtual)
-  // method exists so that derivced classes can do special things, such as
-  // tell the OS to write changes to disk now rather than when convenient.
-}
-
-void PersistentMemoryAllocator::RecordError(int error) const {
-  if (errors_histogram_)
-    errors_histogram_->Add(error);
-}
-
-const volatile void* PersistentMemoryAllocator::GetBlockData(
-    Reference ref,
-    uint32_t type_id,
-    uint32_t size) const {
-  DCHECK(size > 0);
-  const volatile BlockHeader* block =
-      GetBlock(ref, type_id, size, false, false);
-  if (!block)
-    return nullptr;
-  return reinterpret_cast<const volatile char*>(block) + sizeof(BlockHeader);
-}
-
-void PersistentMemoryAllocator::UpdateTrackingHistograms() {
-  DCHECK(!readonly_);
-  if (used_histogram_) {
-    MemoryInfo meminfo;
-    GetMemoryInfo(&meminfo);
-    HistogramBase::Sample used_percent = static_cast<HistogramBase::Sample>(
-        ((meminfo.total - meminfo.free) * 100ULL / meminfo.total));
-    used_histogram_->Add(used_percent);
-  }
-}
-
-
-//----- LocalPersistentMemoryAllocator -----------------------------------------
-
-LocalPersistentMemoryAllocator::LocalPersistentMemoryAllocator(
-    size_t size,
-    uint64_t id,
-    base::StringPiece name)
-    : PersistentMemoryAllocator(AllocateLocalMemory(size),
-                                size, 0, id, name, false) {}
-
-LocalPersistentMemoryAllocator::~LocalPersistentMemoryAllocator() {
-  DeallocateLocalMemory(const_cast<char*>(mem_base_), mem_size_, mem_type_);
-}
-
-// static
-PersistentMemoryAllocator::Memory
-LocalPersistentMemoryAllocator::AllocateLocalMemory(size_t size) {
-  void* address;
-
-#if defined(OS_WIN)
-  address =
-      ::VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
-  if (address)
-    return Memory(address, MEM_VIRTUAL);
-  UmaHistogramSparse("UMA.LocalPersistentMemoryAllocator.Failures.Win",
-                     ::GetLastError());
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
-  // MAP_ANON is deprecated on Linux but MAP_ANONYMOUS is not universal on Mac.
-  // MAP_SHARED is not available on Linux <2.4 but required on Mac.
-  address = ::mmap(nullptr, size, PROT_READ | PROT_WRITE,
-                   MAP_ANON | MAP_SHARED, -1, 0);
-  if (address != MAP_FAILED)
-    return Memory(address, MEM_VIRTUAL);
-  UmaHistogramSparse("UMA.LocalPersistentMemoryAllocator.Failures.Posix",
-                     errno);
-#else
-#error This architecture is not (yet) supported.
-#endif
-
-  // As a last resort, just allocate the memory from the heap. This will
-  // achieve the same basic result but the acquired memory has to be
-  // explicitly zeroed and thus realized immediately (i.e. all pages are
-  // added to the process now istead of only when first accessed).
-  address = malloc(size);
-  DPCHECK(address);
-  memset(address, 0, size);
-  return Memory(address, MEM_MALLOC);
-}
-
-// static
-void LocalPersistentMemoryAllocator::DeallocateLocalMemory(void* memory,
-                                                           size_t size,
-                                                           MemoryType type) {
-  if (type == MEM_MALLOC) {
-    free(memory);
-    return;
-  }
-
-  DCHECK_EQ(MEM_VIRTUAL, type);
-#if defined(OS_WIN)
-  BOOL success = ::VirtualFree(memory, 0, MEM_DECOMMIT);
-  DCHECK(success);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
-  int result = ::munmap(memory, size);
-  DCHECK_EQ(0, result);
-#else
-#error This architecture is not (yet) supported.
-#endif
-}
-
-
-//----- SharedPersistentMemoryAllocator ----------------------------------------
-
-SharedPersistentMemoryAllocator::SharedPersistentMemoryAllocator(
-    std::unique_ptr<SharedMemory> memory,
-    uint64_t id,
-    base::StringPiece name,
-    bool read_only)
-    : PersistentMemoryAllocator(
-          Memory(static_cast<uint8_t*>(memory->memory()), MEM_SHARED),
-          memory->mapped_size(),
-          0,
-          id,
-          name,
-          read_only),
-      shared_memory_(std::move(memory)) {}
-
-SharedPersistentMemoryAllocator::~SharedPersistentMemoryAllocator() = default;
-
-// static
-bool SharedPersistentMemoryAllocator::IsSharedMemoryAcceptable(
-    const SharedMemory& memory) {
-  return IsMemoryAcceptable(memory.memory(), memory.mapped_size(), 0, false);
-}
-
-
-#if !defined(OS_NACL)
-//----- FilePersistentMemoryAllocator ------------------------------------------
-
-FilePersistentMemoryAllocator::FilePersistentMemoryAllocator(
-    std::unique_ptr<MemoryMappedFile> file,
-    size_t max_size,
-    uint64_t id,
-    base::StringPiece name,
-    bool read_only)
-    : PersistentMemoryAllocator(
-          Memory(const_cast<uint8_t*>(file->data()), MEM_FILE),
-          max_size != 0 ? max_size : file->length(),
-          0,
-          id,
-          name,
-          read_only),
-      mapped_file_(std::move(file)) {}
-
-FilePersistentMemoryAllocator::~FilePersistentMemoryAllocator() = default;
-
-// static
-bool FilePersistentMemoryAllocator::IsFileAcceptable(
-    const MemoryMappedFile& file,
-    bool read_only) {
-  return IsMemoryAcceptable(file.data(), file.length(), 0, read_only);
-}
-
-void FilePersistentMemoryAllocator::FlushPartial(size_t length, bool sync) {
-  if (sync)
-    AssertBlockingAllowed();
-  if (IsReadonly())
-    return;
-
-#if defined(OS_WIN)
-  // Windows doesn't support asynchronous flush.
-  AssertBlockingAllowed();
-  BOOL success = ::FlushViewOfFile(data(), length);
-  DPCHECK(success);
-#elif defined(OS_MACOSX)
-  // On OSX, "invalidate" removes all cached pages, forcing a re-read from
-  // disk. That's not applicable to "flush" so omit it.
-  int result =
-      ::msync(const_cast<void*>(data()), length, sync ? MS_SYNC : MS_ASYNC);
-  DCHECK_NE(EINVAL, result);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
-  // On POSIX, "invalidate" forces _other_ processes to recognize what has
-  // been written to disk and so is applicable to "flush".
-  int result = ::msync(const_cast<void*>(data()), length,
-                       MS_INVALIDATE | (sync ? MS_SYNC : MS_ASYNC));
-  DCHECK_NE(EINVAL, result);
-#else
-#error Unsupported OS.
-#endif
-}
-#endif  // !defined(OS_NACL)
-
-//----- DelayedPersistentAllocation --------------------------------------------
-
-// Forwarding constructors.
-DelayedPersistentAllocation::DelayedPersistentAllocation(
-    PersistentMemoryAllocator* allocator,
-    subtle::Atomic32* ref,
-    uint32_t type,
-    size_t size,
-    bool make_iterable)
-    : DelayedPersistentAllocation(
-          allocator,
-          reinterpret_cast<std::atomic<Reference>*>(ref),
-          type,
-          size,
-          0,
-          make_iterable) {}
-
-DelayedPersistentAllocation::DelayedPersistentAllocation(
-    PersistentMemoryAllocator* allocator,
-    subtle::Atomic32* ref,
-    uint32_t type,
-    size_t size,
-    size_t offset,
-    bool make_iterable)
-    : DelayedPersistentAllocation(
-          allocator,
-          reinterpret_cast<std::atomic<Reference>*>(ref),
-          type,
-          size,
-          offset,
-          make_iterable) {}
-
-DelayedPersistentAllocation::DelayedPersistentAllocation(
-    PersistentMemoryAllocator* allocator,
-    std::atomic<Reference>* ref,
-    uint32_t type,
-    size_t size,
-    bool make_iterable)
-    : DelayedPersistentAllocation(allocator,
-                                  ref,
-                                  type,
-                                  size,
-                                  0,
-                                  make_iterable) {}
-
-// Real constructor.
-DelayedPersistentAllocation::DelayedPersistentAllocation(
-    PersistentMemoryAllocator* allocator,
-    std::atomic<Reference>* ref,
-    uint32_t type,
-    size_t size,
-    size_t offset,
-    bool make_iterable)
-    : allocator_(allocator),
-      type_(type),
-      size_(checked_cast<uint32_t>(size)),
-      offset_(checked_cast<uint32_t>(offset)),
-      make_iterable_(make_iterable),
-      reference_(ref) {
-  DCHECK(allocator_);
-  DCHECK_NE(0U, type_);
-  DCHECK_LT(0U, size_);
-  DCHECK(reference_);
-}
-
-DelayedPersistentAllocation::~DelayedPersistentAllocation() = default;
-
-void* DelayedPersistentAllocation::Get() const {
-  // Relaxed operations are acceptable here because it's not protecting the
-  // contents of the allocation in any way.
-  Reference ref = reference_->load(std::memory_order_acquire);
-  if (!ref) {
-    ref = allocator_->Allocate(size_, type_);
-    if (!ref)
-      return nullptr;
-
-    // Store the new reference in its proper location using compare-and-swap.
-    // Use a "strong" exchange to ensure no false-negatives since the operation
-    // cannot be retried.
-    Reference existing = 0;  // Must be mutable; receives actual value.
-    if (reference_->compare_exchange_strong(existing, ref,
-                                            std::memory_order_release,
-                                            std::memory_order_relaxed)) {
-      if (make_iterable_)
-        allocator_->MakeIterable(ref);
-    } else {
-      // Failure indicates that something else has raced ahead, performed the
-      // allocation, and stored its reference. Purge the allocation that was
-      // just done and use the other one instead.
-      DCHECK_EQ(type_, allocator_->GetType(existing));
-      DCHECK_LE(size_, allocator_->GetAllocSize(existing));
-      allocator_->ChangeType(ref, 0, type_, /*clear=*/false);
-      ref = existing;
-    }
-  }
-
-  char* mem = allocator_->GetAsArray<char>(ref, type_, size_);
-  if (!mem) {
-    // This should never happen but be tolerant if it does as corruption from
-    // the outside is something to guard against.
-    NOTREACHED();
-    return nullptr;
-  }
-  return mem + offset_;
-}
-
-}  // namespace base
diff --git a/base/metrics/persistent_memory_allocator.h b/base/metrics/persistent_memory_allocator.h
deleted file mode 100644
index 978a362..0000000
--- a/base/metrics/persistent_memory_allocator.h
+++ /dev/null
@@ -1,872 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_
-#define BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_
-
-#include <stdint.h>
-
-#include <atomic>
-#include <memory>
-#include <type_traits>
-
-#include "base/atomicops.h"
-#include "base/base_export.h"
-#include "base/files/file_path.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/strings/string_piece.h"
-
-namespace base {
-
-class HistogramBase;
-class MemoryMappedFile;
-class SharedMemory;
-
-// Simple allocator for pieces of a memory block that may be persistent
-// to some storage or shared across multiple processes. This class resides
-// under base/metrics because it was written for that purpose. It is,
-// however, fully general-purpose and can be freely moved to base/memory
-// if other uses are found.
-//
-// This class provides for thread-secure (i.e. safe against other threads
-// or processes that may be compromised and thus have malicious intent)
-// allocation of memory within a designated block and also a mechanism by
-// which other threads can learn of these allocations.
-//
-// There is (currently) no way to release an allocated block of data because
-// doing so would risk invalidating pointers held by other processes and
-// greatly complicate the allocation algorithm.
-//
-// Construction of this object can accept new, clean (i.e. zeroed) memory
-// or previously initialized memory. In the first case, construction must
-// be allowed to complete before letting other allocators attach to the same
-// segment. In other words, don't share the segment until at least one
-// allocator has been attached to it.
-//
-// Note that memory not in active use is not accessed so it is possible to
-// use virtual memory, including memory-mapped files, as backing storage with
-// the OS "pinning" new (zeroed) physical RAM pages only as they are needed.
-//
-// OBJECTS: Although the allocator can be used in a "malloc" sense, fetching
-// character arrays and manipulating that memory manually, the better way is
-// generally to use the "object" methods to create and manage allocations. In
-// this way the sizing, type-checking, and construction are all automatic. For
-// this to work, however, every type of stored object must define two public
-// "constexpr" values, kPersistentTypeId and kExpectedInstanceSize, as such:
-//
-// struct MyPersistentObjectType {
-//     // SHA1(MyPersistentObjectType): Increment this if structure changes!
-//     static constexpr uint32_t kPersistentTypeId = 0x3E15F6DE + 1;
-//
-//     // Expected size for 32/64-bit check. Update this if structure changes!
-//     static constexpr size_t kExpectedInstanceSize = 20;
-//
-//     ...
-// };
-//
-// kPersistentTypeId: This value is an arbitrary identifier that allows the
-//   identification of these objects in the allocator, including the ability
-//   to find them via iteration. The number is arbitrary but using the first
-//   four bytes of the SHA1 hash of the type name means that there shouldn't
-//   be any conflicts with other types that may also be stored in the memory.
-//   The fully qualified name (e.g. base::debug::MyPersistentObjectType) could
-//   be used to generate the hash if the type name seems common. Use a command
-//   like this to get the hash: echo -n "MyPersistentObjectType" | sha1sum
-//   If the structure layout changes, ALWAYS increment this number so that
-//   newer versions of the code don't try to interpret persistent data written
-//   by older versions with a different layout.
-//
-// kExpectedInstanceSize: This value is the hard-coded number that matches
-//   what sizeof(T) would return. By providing it explicitly, the allocator can
-//   verify that the structure is compatible between both 32-bit and 64-bit
-//   versions of the code.
-//
-// Using New manages the memory and then calls the default constructor for the
-// object. Given that objects are persistent, no destructor is ever called
-// automatically though a caller can explicitly call Delete to destruct it and
-// change the type to something indicating it is no longer in use.
-//
-// Though persistent memory segments are transferrable between programs built
-// for different natural word widths, they CANNOT be exchanged between CPUs
-// of different endianess. Attempts to do so will simply see the existing data
-// as corrupt and refuse to access any of it.
-class BASE_EXPORT PersistentMemoryAllocator {
- public:
-  typedef uint32_t Reference;
-
-  // These states are used to indicate the overall condition of the memory
-  // segment irrespective of what is stored within it. Because the data is
-  // often persistent and thus needs to be readable by different versions of
-  // a program, these values are fixed and can never change.
-  enum MemoryState : uint8_t {
-    // Persistent memory starts all zeros and so shows "uninitialized".
-    MEMORY_UNINITIALIZED = 0,
-
-    // The header has been written and the memory is ready for use.
-    MEMORY_INITIALIZED = 1,
-
-    // The data should be considered deleted. This would be set when the
-    // allocator is being cleaned up. If file-backed, the file is likely
-    // to be deleted but since deletion can fail for a variety of reasons,
-    // having this extra status means a future reader can realize what
-    // should have happened.
-    MEMORY_DELETED = 2,
-
-    // Outside code can create states starting with this number; these too
-    // must also never change between code versions.
-    MEMORY_USER_DEFINED = 100,
-  };
-
-  // Iterator for going through all iterable memory records in an allocator.
-  // Like the allocator itself, iterators are lock-free and thread-secure.
-  // That means that multiple threads can share an iterator and the same
-  // reference will not be returned twice.
-  //
-  // The order of the items returned by an iterator matches the order in which
-  // MakeIterable() was called on them. Once an allocation is made iterable,
-  // it is always such so the only possible difference between successive
-  // iterations is for more to be added to the end.
-  //
-  // Iteration, in general, is tolerant of corrupted memory. It will return
-  // what it can and stop only when corruption forces it to. Bad corruption
-  // could cause the same object to be returned many times but it will
-  // eventually quit.
-  class BASE_EXPORT Iterator {
-   public:
-    // Constructs an iterator on a given |allocator|, starting at the beginning.
-    // The allocator must live beyond the lifetime of the iterator. This class
-    // has read-only access to the allocator (hence "const") but the returned
-    // references can be used on a read/write version, too.
-    explicit Iterator(const PersistentMemoryAllocator* allocator);
-
-    // As above but resuming from the |starting_after| reference. The first call
-    // to GetNext() will return the next object found after that reference. The
-    // reference must be to an "iterable" object; references to non-iterable
-    // objects (those that never had MakeIterable() called for them) will cause
-    // a run-time error.
-    Iterator(const PersistentMemoryAllocator* allocator,
-             Reference starting_after);
-
-    // Resets the iterator back to the beginning.
-    void Reset();
-
-    // Resets the iterator, resuming from the |starting_after| reference.
-    void Reset(Reference starting_after);
-
-    // Returns the previously retrieved reference, or kReferenceNull if none.
-    // If constructor or reset with a starting_after location, this will return
-    // that value.
-    Reference GetLast();
-
-    // Gets the next iterable, storing that type in |type_return|. The actual
-    // return value is a reference to the allocation inside the allocator or
-    // zero if there are no more. GetNext() may still be called again at a
-    // later time to retrieve any new allocations that have been added.
-    Reference GetNext(uint32_t* type_return);
-
-    // Similar to above but gets the next iterable of a specific |type_match|.
-    // This should not be mixed with calls to GetNext() because any allocations
-    // skipped here due to a type mis-match will never be returned by later
-    // calls to GetNext() meaning it's possible to completely miss entries.
-    Reference GetNextOfType(uint32_t type_match);
-
-    // As above but works using object type.
-    template <typename T>
-    Reference GetNextOfType() {
-      return GetNextOfType(T::kPersistentTypeId);
-    }
-
-    // As above but works using objects and returns null if not found.
-    template <typename T>
-    const T* GetNextOfObject() {
-      return GetAsObject<T>(GetNextOfType<T>());
-    }
-
-    // Converts references to objects. This is a convenience method so that
-    // users of the iterator don't need to also have their own pointer to the
-    // allocator over which the iterator runs in order to retrieve objects.
-    // Because the iterator is not read/write, only "const" objects can be
-    // fetched. Non-const objects can be fetched using the reference on a
-    // non-const (external) pointer to the same allocator (or use const_cast
-    // to remove the qualifier).
-    template <typename T>
-    const T* GetAsObject(Reference ref) const {
-      return allocator_->GetAsObject<T>(ref);
-    }
-
-    // Similar to GetAsObject() but converts references to arrays of things.
-    template <typename T>
-    const T* GetAsArray(Reference ref, uint32_t type_id, size_t count) const {
-      return allocator_->GetAsArray<T>(ref, type_id, count);
-    }
-
-    // Convert a generic pointer back into a reference. A null reference will
-    // be returned if |memory| is not inside the persistent segment or does not
-    // point to an object of the specified |type_id|.
-    Reference GetAsReference(const void* memory, uint32_t type_id) const {
-      return allocator_->GetAsReference(memory, type_id);
-    }
-
-    // As above but convert an object back into a reference.
-    template <typename T>
-    Reference GetAsReference(const T* obj) const {
-      return allocator_->GetAsReference(obj);
-    }
-
-   private:
-    // Weak-pointer to memory allocator being iterated over.
-    const PersistentMemoryAllocator* allocator_;
-
-    // The last record that was returned.
-    std::atomic<Reference> last_record_;
-
-    // The number of records found; used for detecting loops.
-    std::atomic<uint32_t> record_count_;
-
-    DISALLOW_COPY_AND_ASSIGN(Iterator);
-  };
-
-  // Returned information about the internal state of the heap.
-  struct MemoryInfo {
-    size_t total;
-    size_t free;
-  };
-
-  enum : Reference {
-    // A common "null" reference value.
-    kReferenceNull = 0,
-  };
-
-  enum : uint32_t {
-    // A value that will match any type when doing lookups.
-    kTypeIdAny = 0x00000000,
-
-    // A value indicating that the type is in transition. Work is being done
-    // on the contents to prepare it for a new type to come.
-    kTypeIdTransitioning = 0xFFFFFFFF,
-  };
-
-  enum : size_t {
-    kSizeAny = 1  // Constant indicating that any array size is acceptable.
-  };
-
-  // This is the standard file extension (suitable for being passed to the
-  // AddExtension() method of base::FilePath) for dumps of persistent memory.
-  static const base::FilePath::CharType kFileExtension[];
-
-  // The allocator operates on any arbitrary block of memory. Creation and
-  // persisting or sharing of that block with another process is the
-  // responsibility of the caller. The allocator needs to know only the
-  // block's |base| address, the total |size| of the block, and any internal
-  // |page| size (zero if not paged) across which allocations should not span.
-  // The |id| is an arbitrary value the caller can use to identify a
-  // particular memory segment. It will only be loaded during the initial
-  // creation of the segment and can be checked by the caller for consistency.
-  // The |name|, if provided, is used to distinguish histograms for this
-  // allocator. Only the primary owner of the segment should define this value;
-  // other processes can learn it from the shared state. If the underlying
-  // memory is |readonly| then no changes will be made to it. The resulting
-  // object should be stored as a "const" pointer.
-  //
-  // PersistentMemoryAllocator does NOT take ownership of the memory block.
-  // The caller must manage it and ensure it stays available throughout the
-  // lifetime of this object.
-  //
-  // Memory segments for sharing must have had an allocator attached to them
-  // before actually being shared. If the memory segment was just created, it
-  // should be zeroed before being passed here. If it was an existing segment,
-  // the values here will be compared to copies stored in the shared segment
-  // as a guard against corruption.
-  //
-  // Make sure that the memory segment is acceptable (see IsMemoryAcceptable()
-  // method below) before construction if the definition of the segment can
-  // vary in any way at run-time. Invalid memory segments will cause a crash.
-  PersistentMemoryAllocator(void* base, size_t size, size_t page_size,
-                            uint64_t id, base::StringPiece name,
-                            bool readonly);
-  virtual ~PersistentMemoryAllocator();
-
-  // Check if memory segment is acceptable for creation of an Allocator. This
-  // doesn't do any analysis of the data and so doesn't guarantee that the
-  // contents are valid, just that the paramaters won't cause the program to
-  // abort. The IsCorrupt() method will report detection of data problems
-  // found during construction and general operation.
-  static bool IsMemoryAcceptable(const void* data, size_t size,
-                                 size_t page_size, bool readonly);
-
-  // Get the internal identifier for this persistent memory segment.
-  uint64_t Id() const;
-
-  // Get the internal name of this allocator (possibly an empty string).
-  const char* Name() const;
-
-  // Is this segment open only for read?
-  bool IsReadonly() const { return readonly_; }
-
-  // Manage the saved state of the memory.
-  void SetMemoryState(uint8_t memory_state);
-  uint8_t GetMemoryState() const;
-
-  // Create internal histograms for tracking memory use and allocation sizes
-  // for allocator of |name| (which can simply be the result of Name()). This
-  // is done seperately from construction for situations such as when the
-  // histograms will be backed by memory provided by this very allocator.
-  //
-  // IMPORTANT: Callers must update tools/metrics/histograms/histograms.xml
-  // with the following histograms:
-  //    UMA.PersistentAllocator.name.Errors
-  //    UMA.PersistentAllocator.name.UsedPct
-  void CreateTrackingHistograms(base::StringPiece name);
-
-  // Flushes the persistent memory to any backing store. This typically does
-  // nothing but is used by the FilePersistentMemoryAllocator to inform the
-  // OS that all the data should be sent to the disk immediately. This is
-  // useful in the rare case where something has just been stored that needs
-  // to survive a hard shutdown of the machine like from a power failure.
-  // The |sync| parameter indicates if this call should block until the flush
-  // is complete but is only advisory and may or may not have an effect
-  // depending on the capabilities of the OS. Synchronous flushes are allowed
-  // only from theads that are allowed to do I/O but since |sync| is only
-  // advisory, all flushes should be done on IO-capable threads.
-  void Flush(bool sync);
-
-  // Direct access to underlying memory segment. If the segment is shared
-  // across threads or processes, reading data through these values does
-  // not guarantee consistency. Use with care. Do not write.
-  const void* data() const { return const_cast<const char*>(mem_base_); }
-  size_t length() const { return mem_size_; }
-  size_t size() const { return mem_size_; }
-  size_t used() const;
-
-  // Get an object referenced by a |ref|. For safety reasons, the |type_id|
-  // code and size-of(|T|) are compared to ensure the reference is valid
-  // and cannot return an object outside of the memory segment. A |type_id| of
-  // kTypeIdAny (zero) will match any though the size is still checked. NULL is
-  // returned if any problem is detected, such as corrupted storage or incorrect
-  // parameters. Callers MUST check that the returned value is not-null EVERY
-  // TIME before accessing it or risk crashing! Once dereferenced, the pointer
-  // is safe to reuse forever.
-  //
-  // It is essential that the object be of a fixed size. All fields must be of
-  // a defined type that does not change based on the compiler or the CPU
-  // natural word size. Acceptable are char, float, double, and (u)intXX_t.
-  // Unacceptable are int, bool, and wchar_t which are implementation defined
-  // with regards to their size.
-  //
-  // Alignment must also be consistent. A uint64_t after a uint32_t will pad
-  // differently between 32 and 64 bit architectures. Either put the bigger
-  // elements first, group smaller elements into blocks the size of larger
-  // elements, or manually insert padding fields as appropriate for the
-  // largest architecture, including at the end.
-  //
-  // To protected against mistakes, all objects must have the attribute
-  // |kExpectedInstanceSize| (static constexpr size_t)  that is a hard-coded
-  // numerical value -- NNN, not sizeof(T) -- that can be tested. If the
-  // instance size is not fixed, at least one build will fail.
-  //
-  // If the size of a structure changes, the type-ID used to recognize it
-  // should also change so later versions of the code don't try to read
-  // incompatible structures from earlier versions.
-  //
-  // NOTE: Though this method will guarantee that an object of the specified
-  // type can be accessed without going outside the bounds of the memory
-  // segment, it makes no guarantees of the validity of the data within the
-  // object itself. If it is expected that the contents of the segment could
-  // be compromised with malicious intent, the object must be hardened as well.
-  //
-  // Though the persistent data may be "volatile" if it is shared with
-  // other processes, such is not necessarily the case. The internal
-  // "volatile" designation is discarded so as to not propagate the viral
-  // nature of that keyword to the caller. It can add it back, if necessary,
-  // based on knowledge of how the allocator is being used.
-  template <typename T>
-  T* GetAsObject(Reference ref) {
-    static_assert(std::is_standard_layout<T>::value, "only standard objects");
-    static_assert(!std::is_array<T>::value, "use GetAsArray<>()");
-    static_assert(T::kExpectedInstanceSize == sizeof(T), "inconsistent size");
-    return const_cast<T*>(reinterpret_cast<volatile T*>(
-        GetBlockData(ref, T::kPersistentTypeId, sizeof(T))));
-  }
-  template <typename T>
-  const T* GetAsObject(Reference ref) const {
-    static_assert(std::is_standard_layout<T>::value, "only standard objects");
-    static_assert(!std::is_array<T>::value, "use GetAsArray<>()");
-    static_assert(T::kExpectedInstanceSize == sizeof(T), "inconsistent size");
-    return const_cast<const T*>(reinterpret_cast<const volatile T*>(
-        GetBlockData(ref, T::kPersistentTypeId, sizeof(T))));
-  }
-
-  // Like GetAsObject but get an array of simple, fixed-size types.
-  //
-  // Use a |count| of the required number of array elements, or kSizeAny.
-  // GetAllocSize() can be used to calculate the upper bound but isn't reliable
-  // because padding can make space for extra elements that were not written.
-  //
-  // Remember that an array of char is a string but may not be NUL terminated.
-  //
-  // There are no compile-time or run-time checks to ensure 32/64-bit size
-  // compatibilty when using these accessors. Only use fixed-size types such
-  // as char, float, double, or (u)intXX_t.
-  template <typename T>
-  T* GetAsArray(Reference ref, uint32_t type_id, size_t count) {
-    static_assert(std::is_fundamental<T>::value, "use GetAsObject<>()");
-    return const_cast<T*>(reinterpret_cast<volatile T*>(
-        GetBlockData(ref, type_id, count * sizeof(T))));
-  }
-  template <typename T>
-  const T* GetAsArray(Reference ref, uint32_t type_id, size_t count) const {
-    static_assert(std::is_fundamental<T>::value, "use GetAsObject<>()");
-    return const_cast<const char*>(reinterpret_cast<const volatile T*>(
-        GetBlockData(ref, type_id, count * sizeof(T))));
-  }
-
-  // Get the corresponding reference for an object held in persistent memory.
-  // If the |memory| is not valid or the type does not match, a kReferenceNull
-  // result will be returned.
-  Reference GetAsReference(const void* memory, uint32_t type_id) const;
-
-  // Get the number of bytes allocated to a block. This is useful when storing
-  // arrays in order to validate the ending boundary. The returned value will
-  // include any padding added to achieve the required alignment and so could
-  // be larger than given in the original Allocate() request.
-  size_t GetAllocSize(Reference ref) const;
-
-  // Access the internal "type" of an object. This generally isn't necessary
-  // but can be used to "clear" the type and so effectively mark it as deleted
-  // even though the memory stays valid and allocated. Changing the type is
-  // an atomic compare/exchange and so requires knowing the existing value.
-  // It will return false if the existing type is not what is expected.
-  //
-  // Changing the type doesn't mean the data is compatible with the new type.
-  // Passing true for |clear| will zero the memory after the type has been
-  // changed away from |from_type_id| but before it becomes |to_type_id| meaning
-  // that it is done in a manner that is thread-safe. Memory is guaranteed to
-  // be zeroed atomically by machine-word in a monotonically increasing order.
-  //
-  // It will likely be necessary to reconstruct the type before it can be used.
-  // Changing the type WILL NOT invalidate existing pointers to the data, either
-  // in this process or others, so changing the data structure could have
-  // unpredicatable results. USE WITH CARE!
-  uint32_t GetType(Reference ref) const;
-  bool ChangeType(Reference ref,
-                  uint32_t to_type_id,
-                  uint32_t from_type_id,
-                  bool clear);
-
-  // Allocated objects can be added to an internal list that can then be
-  // iterated over by other processes. If an allocated object can be found
-  // another way, such as by having its reference within a different object
-  // that will be made iterable, then this call is not necessary. This always
-  // succeeds unless corruption is detected; check IsCorrupted() to find out.
-  // Once an object is made iterable, its position in iteration can never
-  // change; new iterable objects will always be added after it in the series.
-  // Changing the type does not alter its "iterable" status.
-  void MakeIterable(Reference ref);
-
-  // Get the information about the amount of free space in the allocator. The
-  // amount of free space should be treated as approximate due to extras from
-  // alignment and metadata. Concurrent allocations from other threads will
-  // also make the true amount less than what is reported.
-  void GetMemoryInfo(MemoryInfo* meminfo) const;
-
-  // If there is some indication that the memory has become corrupted,
-  // calling this will attempt to prevent further damage by indicating to
-  // all processes that something is not as expected.
-  void SetCorrupt() const;
-
-  // This can be called to determine if corruption has been detected in the
-  // segment, possibly my a malicious actor. Once detected, future allocations
-  // will fail and iteration may not locate all objects.
-  bool IsCorrupt() const;
-
-  // Flag set if an allocation has failed because the memory segment was full.
-  bool IsFull() const;
-
-  // Update those "tracking" histograms which do not get updates during regular
-  // operation, such as how much memory is currently used. This should be
-  // called before such information is to be displayed or uploaded.
-  void UpdateTrackingHistograms();
-
-  // While the above works much like malloc & free, these next methods provide
-  // an "object" interface similar to new and delete.
-
-  // Reserve space in the memory segment of the desired |size| and |type_id|.
-  // A return value of zero indicates the allocation failed, otherwise the
-  // returned reference can be used by any process to get a real pointer via
-  // the GetAsObject() or GetAsArray calls. The actual allocated size may be
-  // larger and will always be a multiple of 8 bytes (64 bits).
-  Reference Allocate(size_t size, uint32_t type_id);
-
-  // Allocate and construct an object in persistent memory. The type must have
-  // both (size_t) kExpectedInstanceSize and (uint32_t) kPersistentTypeId
-  // static constexpr fields that are used to ensure compatibility between
-  // software versions. An optional size parameter can be specified to force
-  // the allocation to be bigger than the size of the object; this is useful
-  // when the last field is actually variable length.
-  template <typename T>
-  T* New(size_t size) {
-    if (size < sizeof(T))
-      size = sizeof(T);
-    Reference ref = Allocate(size, T::kPersistentTypeId);
-    void* mem =
-        const_cast<void*>(GetBlockData(ref, T::kPersistentTypeId, size));
-    if (!mem)
-      return nullptr;
-    DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(mem) & (alignof(T) - 1));
-    return new (mem) T();
-  }
-  template <typename T>
-  T* New() {
-    return New<T>(sizeof(T));
-  }
-
-  // Similar to New, above, but construct the object out of an existing memory
-  // block and of an expected type. If |clear| is true, memory will be zeroed
-  // before construction. Though this is not standard object behavior, it
-  // is present to match with new allocations that always come from zeroed
-  // memory. Anything previously present simply ceases to exist; no destructor
-  // is called for it so explicitly Delete() the old object first if need be.
-  // Calling this will not invalidate existing pointers to the object, either
-  // in this process or others, so changing the object could have unpredictable
-  // results. USE WITH CARE!
-  template <typename T>
-  T* New(Reference ref, uint32_t from_type_id, bool clear) {
-    DCHECK_LE(sizeof(T), GetAllocSize(ref)) << "alloc not big enough for obj";
-    // Make sure the memory is appropriate. This won't be used until after
-    // the type is changed but checking first avoids the possibility of having
-    // to change the type back.
-    void* mem = const_cast<void*>(GetBlockData(ref, 0, sizeof(T)));
-    if (!mem)
-      return nullptr;
-    // Ensure the allocator's internal alignment is sufficient for this object.
-    // This protects against coding errors in the allocator.
-    DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(mem) & (alignof(T) - 1));
-    // Change the type, clearing the memory if so desired. The new type is
-    // "transitioning" so that there is no race condition with the construction
-    // of the object should another thread be simultaneously iterating over
-    // data. This will "acquire" the memory so no changes get reordered before
-    // it.
-    if (!ChangeType(ref, kTypeIdTransitioning, from_type_id, clear))
-      return nullptr;
-    // Construct an object of the desired type on this memory, just as if
-    // New() had been called to create it.
-    T* obj = new (mem) T();
-    // Finally change the type to the desired one. This will "release" all of
-    // the changes above and so provide a consistent view to other threads.
-    bool success =
-        ChangeType(ref, T::kPersistentTypeId, kTypeIdTransitioning, false);
-    DCHECK(success);
-    return obj;
-  }
-
-  // Deletes an object by destructing it and then changing the type to a
-  // different value (default 0).
-  template <typename T>
-  void Delete(T* obj, uint32_t new_type) {
-    // Get the reference for the object.
-    Reference ref = GetAsReference<T>(obj);
-    // First change the type to "transitioning" so there is no race condition
-    // where another thread could find the object through iteration while it
-    // is been destructed. This will "acquire" the memory so no changes get
-    // reordered before it. It will fail if |ref| is invalid.
-    if (!ChangeType(ref, kTypeIdTransitioning, T::kPersistentTypeId, false))
-      return;
-    // Destruct the object.
-    obj->~T();
-    // Finally change the type to the desired value. This will "release" all
-    // the changes above.
-    bool success = ChangeType(ref, new_type, kTypeIdTransitioning, false);
-    DCHECK(success);
-  }
-  template <typename T>
-  void Delete(T* obj) {
-    Delete<T>(obj, 0);
-  }
-
-  // As above but works with objects allocated from persistent memory.
-  template <typename T>
-  Reference GetAsReference(const T* obj) const {
-    return GetAsReference(obj, T::kPersistentTypeId);
-  }
-
-  // As above but works with an object allocated from persistent memory.
-  template <typename T>
-  void MakeIterable(const T* obj) {
-    MakeIterable(GetAsReference<T>(obj));
-  }
-
- protected:
-  enum MemoryType {
-    MEM_EXTERNAL,
-    MEM_MALLOC,
-    MEM_VIRTUAL,
-    MEM_SHARED,
-    MEM_FILE,
-  };
-
-  struct Memory {
-    Memory(void* b, MemoryType t) : base(b), type(t) {}
-
-    void* base;
-    MemoryType type;
-  };
-
-  // Constructs the allocator. Everything is the same as the public allocator
-  // except |memory| which is a structure with additional information besides
-  // the base address.
-  PersistentMemoryAllocator(Memory memory, size_t size, size_t page_size,
-                            uint64_t id, base::StringPiece name,
-                            bool readonly);
-
-  // Implementation of Flush that accepts how much to flush.
-  virtual void FlushPartial(size_t length, bool sync);
-
-  volatile char* const mem_base_;  // Memory base. (char so sizeof guaranteed 1)
-  const MemoryType mem_type_;      // Type of memory allocation.
-  const uint32_t mem_size_;        // Size of entire memory segment.
-  const uint32_t mem_page_;        // Page size allocations shouldn't cross.
-
- private:
-  struct SharedMetadata;
-  struct BlockHeader;
-  static const uint32_t kAllocAlignment;
-  static const Reference kReferenceQueue;
-
-  // The shared metadata is always located at the top of the memory segment.
-  // These convenience functions eliminate constant casting of the base
-  // pointer within the code.
-  const SharedMetadata* shared_meta() const {
-    return reinterpret_cast<const SharedMetadata*>(
-        const_cast<const char*>(mem_base_));
-  }
-  SharedMetadata* shared_meta() {
-    return reinterpret_cast<SharedMetadata*>(const_cast<char*>(mem_base_));
-  }
-
-  // Actual method for doing the allocation.
-  Reference AllocateImpl(size_t size, uint32_t type_id);
-
-  // Get the block header associated with a specific reference.
-  const volatile BlockHeader* GetBlock(Reference ref, uint32_t type_id,
-                                       uint32_t size, bool queue_ok,
-                                       bool free_ok) const;
-  volatile BlockHeader* GetBlock(Reference ref, uint32_t type_id, uint32_t size,
-                                 bool queue_ok, bool free_ok) {
-      return const_cast<volatile BlockHeader*>(
-          const_cast<const PersistentMemoryAllocator*>(this)->GetBlock(
-              ref, type_id, size, queue_ok, free_ok));
-  }
-
-  // Get the actual data within a block associated with a specific reference.
-  const volatile void* GetBlockData(Reference ref, uint32_t type_id,
-                                    uint32_t size) const;
-  volatile void* GetBlockData(Reference ref, uint32_t type_id,
-                              uint32_t size) {
-      return const_cast<volatile void*>(
-          const_cast<const PersistentMemoryAllocator*>(this)->GetBlockData(
-              ref, type_id, size));
-  }
-
-  // Record an error in the internal histogram.
-  void RecordError(int error) const;
-
-  const size_t vm_page_size_;          // The page size used by the OS.
-  const bool readonly_;                // Indicates access to read-only memory.
-  mutable std::atomic<bool> corrupt_;  // Local version of "corrupted" flag.
-
-  HistogramBase* allocs_histogram_;  // Histogram recording allocs.
-  HistogramBase* used_histogram_;    // Histogram recording used space.
-  HistogramBase* errors_histogram_;  // Histogram recording errors.
-
-  friend class PersistentMemoryAllocatorTest;
-  FRIEND_TEST_ALL_PREFIXES(PersistentMemoryAllocatorTest, AllocateAndIterate);
-  DISALLOW_COPY_AND_ASSIGN(PersistentMemoryAllocator);
-};
-
-
-// This allocator uses a local memory block it allocates from the general
-// heap. It is generally used when some kind of "death rattle" handler will
-// save the contents to persistent storage during process shutdown. It is
-// also useful for testing.
-class BASE_EXPORT LocalPersistentMemoryAllocator
-    : public PersistentMemoryAllocator {
- public:
-  LocalPersistentMemoryAllocator(size_t size, uint64_t id,
-                                 base::StringPiece name);
-  ~LocalPersistentMemoryAllocator() override;
-
- private:
-  // Allocates a block of local memory of the specified |size|, ensuring that
-  // the memory will not be physically allocated until accessed and will read
-  // as zero when that happens.
-  static Memory AllocateLocalMemory(size_t size);
-
-  // Deallocates a block of local |memory| of the specified |size|.
-  static void DeallocateLocalMemory(void* memory, size_t size, MemoryType type);
-
-  DISALLOW_COPY_AND_ASSIGN(LocalPersistentMemoryAllocator);
-};
-
-
-// This allocator takes a shared-memory object and performs allocation from
-// it. The memory must be previously mapped via Map() or MapAt(). The allocator
-// takes ownership of the memory object.
-class BASE_EXPORT SharedPersistentMemoryAllocator
-    : public PersistentMemoryAllocator {
- public:
-  SharedPersistentMemoryAllocator(std::unique_ptr<SharedMemory> memory,
-                                  uint64_t id,
-                                  base::StringPiece name,
-                                  bool read_only);
-  ~SharedPersistentMemoryAllocator() override;
-
-  SharedMemory* shared_memory() { return shared_memory_.get(); }
-
-  // Ensure that the memory isn't so invalid that it would crash when passing it
-  // to the allocator. This doesn't guarantee the data is valid, just that it
-  // won't cause the program to abort. The existing IsCorrupt() call will handle
-  // the rest.
-  static bool IsSharedMemoryAcceptable(const SharedMemory& memory);
-
- private:
-  std::unique_ptr<SharedMemory> shared_memory_;
-
-  DISALLOW_COPY_AND_ASSIGN(SharedPersistentMemoryAllocator);
-};
-
-
-#if !defined(OS_NACL)  // NACL doesn't support any kind of file access in build.
-// This allocator takes a memory-mapped file object and performs allocation
-// from it. The allocator takes ownership of the file object.
-class BASE_EXPORT FilePersistentMemoryAllocator
-    : public PersistentMemoryAllocator {
- public:
-  // A |max_size| of zero will use the length of the file as the maximum
-  // size. The |file| object must have been already created with sufficient
-  // permissions (read, read/write, or read/write/extend).
-  FilePersistentMemoryAllocator(std::unique_ptr<MemoryMappedFile> file,
-                                size_t max_size,
-                                uint64_t id,
-                                base::StringPiece name,
-                                bool read_only);
-  ~FilePersistentMemoryAllocator() override;
-
-  // Ensure that the file isn't so invalid that it would crash when passing it
-  // to the allocator. This doesn't guarantee the file is valid, just that it
-  // won't cause the program to abort. The existing IsCorrupt() call will handle
-  // the rest.
-  static bool IsFileAcceptable(const MemoryMappedFile& file, bool read_only);
-
- protected:
-  // PersistentMemoryAllocator:
-  void FlushPartial(size_t length, bool sync) override;
-
- private:
-  std::unique_ptr<MemoryMappedFile> mapped_file_;
-
-  DISALLOW_COPY_AND_ASSIGN(FilePersistentMemoryAllocator);
-};
-#endif  // !defined(OS_NACL)
-
-// An allocation that is defined but not executed until required at a later
-// time. This allows for potential users of an allocation to be decoupled
-// from the logic that defines it. In addition, there can be multiple users
-// of the same allocation or any region thereof that are guaranteed to always
-// use the same space. It's okay to copy/move these objects.
-//
-// This is a top-level class instead of an inner class of the PMA so that it
-// can be forward-declared in other header files without the need to include
-// the full contents of this file.
-class BASE_EXPORT DelayedPersistentAllocation {
- public:
-  using Reference = PersistentMemoryAllocator::Reference;
-
-  // Creates a delayed allocation using the specified |allocator|. When
-  // needed, the memory will be allocated using the specified |type| and
-  // |size|. If |offset| is given, the returned pointer will be at that
-  // offset into the segment; this allows combining allocations into a
-  // single persistent segment to reduce overhead and means an "all or
-  // nothing" request. Note that |size| is always the total memory size
-  // and |offset| is just indicating the start of a block within it.  If
-  // |make_iterable| was true, the allocation will made iterable when it
-  // is created; already existing allocations are not changed.
-  //
-  // Once allocated, a reference to the segment will be stored at |ref|.
-  // This shared location must be initialized to zero (0); it is checked
-  // with every Get() request to see if the allocation has already been
-  // done. If reading |ref| outside of this object, be sure to do an
-  // "acquire" load. Don't write to it -- leave that to this object.
-  //
-  // For convenience, methods taking both Atomic32 and std::atomic<Reference>
-  // are defined.
-  DelayedPersistentAllocation(PersistentMemoryAllocator* allocator,
-                              subtle::Atomic32* ref,
-                              uint32_t type,
-                              size_t size,
-                              bool make_iterable);
-  DelayedPersistentAllocation(PersistentMemoryAllocator* allocator,
-                              subtle::Atomic32* ref,
-                              uint32_t type,
-                              size_t size,
-                              size_t offset,
-                              bool make_iterable);
-  DelayedPersistentAllocation(PersistentMemoryAllocator* allocator,
-                              std::atomic<Reference>* ref,
-                              uint32_t type,
-                              size_t size,
-                              bool make_iterable);
-  DelayedPersistentAllocation(PersistentMemoryAllocator* allocator,
-                              std::atomic<Reference>* ref,
-                              uint32_t type,
-                              size_t size,
-                              size_t offset,
-                              bool make_iterable);
-  ~DelayedPersistentAllocation();
-
-  // Gets a pointer to the defined allocation. This will realize the request
-  // and update the reference provided during construction. The memory will
-  // be zeroed the first time it is returned, after that it is shared with
-  // all other Get() requests and so shows any changes made to it elsewhere.
-  //
-  // If the allocation fails for any reason, null will be returned. This works
-  // even on "const" objects because the allocation is already defined, just
-  // delayed.
-  void* Get() const;
-
-  // Gets the internal reference value. If this returns a non-zero value then
-  // a subsequent call to Get() will do nothing but convert that reference into
-  // a memory location -- useful for accessing an existing allocation without
-  // creating one unnecessarily.
-  Reference reference() const {
-    return reference_->load(std::memory_order_relaxed);
-  }
-
- private:
-  // The underlying object that does the actual allocation of memory. Its
-  // lifetime must exceed that of all DelayedPersistentAllocation objects
-  // that use it.
-  PersistentMemoryAllocator* const allocator_;
-
-  // The desired type and size of the allocated segment plus the offset
-  // within it for the defined request.
-  const uint32_t type_;
-  const uint32_t size_;
-  const uint32_t offset_;
-
-  // Flag indicating if allocation should be made iterable when done.
-  const bool make_iterable_;
-
-  // The location at which a reference to the allocated segment is to be
-  // stored once the allocation is complete. If multiple delayed allocations
-  // share the same pointer then an allocation on one will amount to an
-  // allocation for all.
-  volatile std::atomic<Reference>* const reference_;
-
-  // No DISALLOW_COPY_AND_ASSIGN as it's okay to copy/move these objects.
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_
diff --git a/base/metrics/persistent_sample_map.cc b/base/metrics/persistent_sample_map.cc
deleted file mode 100644
index f38b9d1..0000000
--- a/base/metrics/persistent_sample_map.cc
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/persistent_sample_map.h"
-
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/metrics/persistent_histogram_allocator.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/stl_util.h"
-
-namespace base {
-
-typedef HistogramBase::Count Count;
-typedef HistogramBase::Sample Sample;
-
-namespace {
-
-// An iterator for going through a PersistentSampleMap. The logic here is
-// identical to that of SampleMapIterator but with different data structures.
-// Changes here likely need to be duplicated there.
-class PersistentSampleMapIterator : public SampleCountIterator {
- public:
-  typedef std::map<HistogramBase::Sample, HistogramBase::Count*>
-      SampleToCountMap;
-
-  explicit PersistentSampleMapIterator(const SampleToCountMap& sample_counts);
-  ~PersistentSampleMapIterator() override;
-
-  // SampleCountIterator:
-  bool Done() const override;
-  void Next() override;
-  void Get(HistogramBase::Sample* min,
-           int64_t* max,
-           HistogramBase::Count* count) const override;
-
- private:
-  void SkipEmptyBuckets();
-
-  SampleToCountMap::const_iterator iter_;
-  const SampleToCountMap::const_iterator end_;
-};
-
-PersistentSampleMapIterator::PersistentSampleMapIterator(
-    const SampleToCountMap& sample_counts)
-    : iter_(sample_counts.begin()),
-      end_(sample_counts.end()) {
-  SkipEmptyBuckets();
-}
-
-PersistentSampleMapIterator::~PersistentSampleMapIterator() = default;
-
-bool PersistentSampleMapIterator::Done() const {
-  return iter_ == end_;
-}
-
-void PersistentSampleMapIterator::Next() {
-  DCHECK(!Done());
-  ++iter_;
-  SkipEmptyBuckets();
-}
-
-void PersistentSampleMapIterator::Get(Sample* min,
-                                      int64_t* max,
-                                      Count* count) const {
-  DCHECK(!Done());
-  if (min)
-    *min = iter_->first;
-  if (max)
-    *max = strict_cast<int64_t>(iter_->first) + 1;
-  if (count)
-    *count = *iter_->second;
-}
-
-void PersistentSampleMapIterator::SkipEmptyBuckets() {
-  while (!Done() && *iter_->second == 0) {
-    ++iter_;
-  }
-}
-
-// This structure holds an entry for a PersistentSampleMap within a persistent
-// memory allocator. The "id" must be unique across all maps held by an
-// allocator or they will get attached to the wrong sample map.
-struct SampleRecord {
-  // SHA1(SampleRecord): Increment this if structure changes!
-  static constexpr uint32_t kPersistentTypeId = 0x8FE6A69F + 1;
-
-  // Expected size for 32/64-bit check.
-  static constexpr size_t kExpectedInstanceSize = 16;
-
-  uint64_t id;   // Unique identifier of owner.
-  Sample value;  // The value for which this record holds a count.
-  Count count;   // The count associated with the above value.
-};
-
-}  // namespace
-
-PersistentSampleMap::PersistentSampleMap(
-    uint64_t id,
-    PersistentHistogramAllocator* allocator,
-    Metadata* meta)
-    : HistogramSamples(id, meta), allocator_(allocator) {}
-
-PersistentSampleMap::~PersistentSampleMap() {
-  if (records_)
-    records_->Release(this);
-}
-
-void PersistentSampleMap::Accumulate(Sample value, Count count) {
-#if 0  // TODO(bcwhite) Re-enable efficient version after crbug.com/682680.
-  *GetOrCreateSampleCountStorage(value) += count;
-#else
-  Count* local_count_ptr = GetOrCreateSampleCountStorage(value);
-  if (count < 0) {
-    if (*local_count_ptr < -count)
-      RecordNegativeSample(SAMPLES_ACCUMULATE_WENT_NEGATIVE, -count);
-    else
-      RecordNegativeSample(SAMPLES_ACCUMULATE_NEGATIVE_COUNT, -count);
-    *local_count_ptr += count;
-  } else {
-    Sample old_value = *local_count_ptr;
-    Sample new_value = old_value + count;
-    *local_count_ptr = new_value;
-    if ((new_value >= 0) != (old_value >= 0))
-      RecordNegativeSample(SAMPLES_ACCUMULATE_OVERFLOW, count);
-  }
-#endif
-  IncreaseSumAndCount(strict_cast<int64_t>(count) * value, count);
-}
-
-Count PersistentSampleMap::GetCount(Sample value) const {
-  // Have to override "const" to make sure all samples have been loaded before
-  // being able to know what value to return.
-  Count* count_pointer =
-      const_cast<PersistentSampleMap*>(this)->GetSampleCountStorage(value);
-  return count_pointer ? *count_pointer : 0;
-}
-
-Count PersistentSampleMap::TotalCount() const {
-  // Have to override "const" in order to make sure all samples have been
-  // loaded before trying to iterate over the map.
-  const_cast<PersistentSampleMap*>(this)->ImportSamples(-1, true);
-
-  Count count = 0;
-  for (const auto& entry : sample_counts_) {
-    count += *entry.second;
-  }
-  return count;
-}
-
-std::unique_ptr<SampleCountIterator> PersistentSampleMap::Iterator() const {
-  // Have to override "const" in order to make sure all samples have been
-  // loaded before trying to iterate over the map.
-  const_cast<PersistentSampleMap*>(this)->ImportSamples(-1, true);
-  return WrapUnique(new PersistentSampleMapIterator(sample_counts_));
-}
-
-// static
-PersistentMemoryAllocator::Reference
-PersistentSampleMap::GetNextPersistentRecord(
-    PersistentMemoryAllocator::Iterator& iterator,
-    uint64_t* sample_map_id) {
-  const SampleRecord* record = iterator.GetNextOfObject<SampleRecord>();
-  if (!record)
-    return 0;
-
-  *sample_map_id = record->id;
-  return iterator.GetAsReference(record);
-}
-
-// static
-PersistentMemoryAllocator::Reference
-PersistentSampleMap::CreatePersistentRecord(
-    PersistentMemoryAllocator* allocator,
-    uint64_t sample_map_id,
-    Sample value) {
-  SampleRecord* record = allocator->New<SampleRecord>();
-  if (!record) {
-    NOTREACHED() << "full=" << allocator->IsFull()
-                 << ", corrupt=" << allocator->IsCorrupt();
-    return 0;
-  }
-
-  record->id = sample_map_id;
-  record->value = value;
-  record->count = 0;
-
-  PersistentMemoryAllocator::Reference ref = allocator->GetAsReference(record);
-  allocator->MakeIterable(ref);
-  return ref;
-}
-
-bool PersistentSampleMap::AddSubtractImpl(SampleCountIterator* iter,
-                                          Operator op) {
-  Sample min;
-  int64_t max;
-  Count count;
-  for (; !iter->Done(); iter->Next()) {
-    iter->Get(&min, &max, &count);
-    if (count == 0)
-      continue;
-    if (strict_cast<int64_t>(min) + 1 != max)
-      return false;  // SparseHistogram only supports bucket with size 1.
-    *GetOrCreateSampleCountStorage(min) +=
-        (op == HistogramSamples::ADD) ? count : -count;
-  }
-  return true;
-}
-
-Count* PersistentSampleMap::GetSampleCountStorage(Sample value) {
-  // If |value| is already in the map, just return that.
-  auto it = sample_counts_.find(value);
-  if (it != sample_counts_.end())
-    return it->second;
-
-  // Import any new samples from persistent memory looking for the value.
-  return ImportSamples(value, false);
-}
-
-Count* PersistentSampleMap::GetOrCreateSampleCountStorage(Sample value) {
-  // Get any existing count storage.
-  Count* count_pointer = GetSampleCountStorage(value);
-  if (count_pointer)
-    return count_pointer;
-
-  // Create a new record in persistent memory for the value. |records_| will
-  // have been initialized by the GetSampleCountStorage() call above.
-  DCHECK(records_);
-  PersistentMemoryAllocator::Reference ref = records_->CreateNew(value);
-  if (!ref) {
-    // If a new record could not be created then the underlying allocator is
-    // full or corrupt. Instead, allocate the counter from the heap. This
-    // sample will not be persistent, will not be shared, and will leak...
-    // but it's better than crashing.
-    count_pointer = new Count(0);
-    sample_counts_[value] = count_pointer;
-    return count_pointer;
-  }
-
-  // A race condition between two independent processes (i.e. two independent
-  // histogram objects sharing the same sample data) could cause two of the
-  // above records to be created. The allocator, however, forces a strict
-  // ordering on iterable objects so use the import method to actually add the
-  // just-created record. This ensures that all PersistentSampleMap objects
-  // will always use the same record, whichever was first made iterable.
-  // Thread-safety within a process where multiple threads use the same
-  // histogram object is delegated to the controlling histogram object which,
-  // for sparse histograms, is a lock object.
-  count_pointer = ImportSamples(value, false);
-  DCHECK(count_pointer);
-  return count_pointer;
-}
-
-PersistentSampleMapRecords* PersistentSampleMap::GetRecords() {
-  // The |records_| pointer is lazily fetched from the |allocator_| only on
-  // first use. Sometimes duplicate histograms are created by race conditions
-  // and if both were to grab the records object, there would be a conflict.
-  // Use of a histogram, and thus a call to this method, won't occur until
-  // after the histogram has been de-dup'd.
-  if (!records_)
-    records_ = allocator_->UseSampleMapRecords(id(), this);
-  return records_;
-}
-
-Count* PersistentSampleMap::ImportSamples(Sample until_value,
-                                          bool import_everything) {
-  Count* found_count = nullptr;
-  PersistentMemoryAllocator::Reference ref;
-  PersistentSampleMapRecords* records = GetRecords();
-  while ((ref = records->GetNext()) != 0) {
-    SampleRecord* record = records->GetAsObject<SampleRecord>(ref);
-    if (!record)
-      continue;
-
-    DCHECK_EQ(id(), record->id);
-
-    // Check if the record's value is already known.
-    if (!ContainsKey(sample_counts_, record->value)) {
-      // No: Add it to map of known values.
-      sample_counts_[record->value] = &record->count;
-    } else {
-      // Yes: Ignore it; it's a duplicate caused by a race condition -- see
-      // code & comment in GetOrCreateSampleCountStorage() for details.
-      // Check that nothing ever operated on the duplicate record.
-      DCHECK_EQ(0, record->count);
-    }
-
-    // Check if it's the value being searched for and, if so, keep a pointer
-    // to return later. Stop here unless everything is being imported.
-    // Because race conditions can cause multiple records for a single value,
-    // be sure to return the first one found.
-    if (record->value == until_value) {
-      if (!found_count)
-        found_count = &record->count;
-      if (!import_everything)
-        break;
-    }
-  }
-
-  return found_count;
-}
-
-}  // namespace base
diff --git a/base/metrics/persistent_sample_map.h b/base/metrics/persistent_sample_map.h
deleted file mode 100644
index 853f862..0000000
--- a/base/metrics/persistent_sample_map.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// PersistentSampleMap implements HistogramSamples interface. It is used
-// by the SparseHistogram class to store samples in persistent memory which
-// allows it to be shared between processes or live across restarts.
-
-#ifndef BASE_METRICS_PERSISTENT_SAMPLE_MAP_H_
-#define BASE_METRICS_PERSISTENT_SAMPLE_MAP_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/persistent_memory_allocator.h"
-
-namespace base {
-
-class PersistentHistogramAllocator;
-class PersistentSampleMapRecords;
-
-// The logic here is similar to that of SampleMap but with different data
-// structures. Changes here likely need to be duplicated there.
-class BASE_EXPORT PersistentSampleMap : public HistogramSamples {
- public:
-  // Constructs a persistent sample map using a PersistentHistogramAllocator
-  // as the data source for persistent records.
-  PersistentSampleMap(uint64_t id,
-                      PersistentHistogramAllocator* allocator,
-                      Metadata* meta);
-
-  ~PersistentSampleMap() override;
-
-  // HistogramSamples:
-  void Accumulate(HistogramBase::Sample value,
-                  HistogramBase::Count count) override;
-  HistogramBase::Count GetCount(HistogramBase::Sample value) const override;
-  HistogramBase::Count TotalCount() const override;
-  std::unique_ptr<SampleCountIterator> Iterator() const override;
-
-  // Uses a persistent-memory |iterator| to locate and return information about
-  // the next record holding information for a PersistentSampleMap. The record
-  // could be for any Map so return the |sample_map_id| as well.
-  static PersistentMemoryAllocator::Reference GetNextPersistentRecord(
-      PersistentMemoryAllocator::Iterator& iterator,
-      uint64_t* sample_map_id);
-
-  // Creates a new record in an |allocator| storing count information for a
-  // specific sample |value| of a histogram with the given |sample_map_id|.
-  static PersistentMemoryAllocator::Reference CreatePersistentRecord(
-      PersistentMemoryAllocator* allocator,
-      uint64_t sample_map_id,
-      HistogramBase::Sample value);
-
- protected:
-  // Performs arithemetic. |op| is ADD or SUBTRACT.
-  bool AddSubtractImpl(SampleCountIterator* iter, Operator op) override;
-
-  // Gets a pointer to a "count" corresponding to a given |value|. Returns NULL
-  // if sample does not exist.
-  HistogramBase::Count* GetSampleCountStorage(HistogramBase::Sample value);
-
-  // Gets a pointer to a "count" corresponding to a given |value|, creating
-  // the sample (initialized to zero) if it does not already exists.
-  HistogramBase::Count* GetOrCreateSampleCountStorage(
-      HistogramBase::Sample value);
-
- private:
-  // Gets the object that manages persistent records. This returns the
-  // |records_| member after first initializing it if necessary.
-  PersistentSampleMapRecords* GetRecords();
-
-  // Imports samples from persistent memory by iterating over all sample
-  // records found therein, adding them to the sample_counts_ map. If a
-  // count for the sample |until_value| is found, stop the import and return
-  // a pointer to that counter. If that value is not found, null will be
-  // returned after all currently available samples have been loaded. Pass
-  // true for |import_everything| to force the importing of all available
-  // samples even if a match is found.
-  HistogramBase::Count* ImportSamples(HistogramBase::Sample until_value,
-                                      bool import_everything);
-
-  // All created/loaded sample values and their associated counts. The storage
-  // for the actual Count numbers is owned by the |records_| object and its
-  // underlying allocator.
-  std::map<HistogramBase::Sample, HistogramBase::Count*> sample_counts_;
-
-  // The allocator that manages histograms inside persistent memory. This is
-  // owned externally and is expected to live beyond the life of this object.
-  PersistentHistogramAllocator* allocator_;
-
-  // The object that manages sample records inside persistent memory. This is
-  // owned by the |allocator_| object (above) and so, like it, is expected to
-  // live beyond the life of this object. This value is lazily-initialized on
-  // first use via the GetRecords() accessor method.
-  PersistentSampleMapRecords* records_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(PersistentSampleMap);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_PERSISTENT_SAMPLE_MAP_H_
diff --git a/base/metrics/record_histogram_checker.h b/base/metrics/record_histogram_checker.h
deleted file mode 100644
index 75bc336..0000000
--- a/base/metrics/record_histogram_checker.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_RECORD_HISTOGRAM_CHECKER_H_
-#define BASE_METRICS_RECORD_HISTOGRAM_CHECKER_H_
-
-#include <stdint.h>
-
-#include "base/base_export.h"
-
-namespace base {
-
-// RecordHistogramChecker provides an interface for checking whether
-// the given histogram should be recorded.
-class BASE_EXPORT RecordHistogramChecker {
- public:
-  virtual ~RecordHistogramChecker() = default;
-
-  // Returns true iff the given histogram should be recorded.
-  // This method may be called on any thread, so it should not mutate any state.
-  virtual bool ShouldRecord(uint64_t histogram_hash) const = 0;
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_RECORD_HISTOGRAM_CHECKER_H_
diff --git a/base/metrics/sample_map.cc b/base/metrics/sample_map.cc
deleted file mode 100644
index c6dce29..0000000
--- a/base/metrics/sample_map.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/sample_map.h"
-
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/stl_util.h"
-
-namespace base {
-
-typedef HistogramBase::Count Count;
-typedef HistogramBase::Sample Sample;
-
-namespace {
-
-// An iterator for going through a SampleMap. The logic here is identical
-// to that of PersistentSampleMapIterator but with different data structures.
-// Changes here likely need to be duplicated there.
-class SampleMapIterator : public SampleCountIterator {
- public:
-  typedef std::map<HistogramBase::Sample, HistogramBase::Count>
-      SampleToCountMap;
-
-  explicit SampleMapIterator(const SampleToCountMap& sample_counts);
-  ~SampleMapIterator() override;
-
-  // SampleCountIterator:
-  bool Done() const override;
-  void Next() override;
-  void Get(HistogramBase::Sample* min,
-           int64_t* max,
-           HistogramBase::Count* count) const override;
-
- private:
-  void SkipEmptyBuckets();
-
-  SampleToCountMap::const_iterator iter_;
-  const SampleToCountMap::const_iterator end_;
-};
-
-SampleMapIterator::SampleMapIterator(const SampleToCountMap& sample_counts)
-    : iter_(sample_counts.begin()),
-      end_(sample_counts.end()) {
-  SkipEmptyBuckets();
-}
-
-SampleMapIterator::~SampleMapIterator() = default;
-
-bool SampleMapIterator::Done() const {
-  return iter_ == end_;
-}
-
-void SampleMapIterator::Next() {
-  DCHECK(!Done());
-  ++iter_;
-  SkipEmptyBuckets();
-}
-
-void SampleMapIterator::Get(Sample* min, int64_t* max, Count* count) const {
-  DCHECK(!Done());
-  if (min)
-    *min = iter_->first;
-  if (max)
-    *max = strict_cast<int64_t>(iter_->first) + 1;
-  if (count)
-    *count = iter_->second;
-}
-
-void SampleMapIterator::SkipEmptyBuckets() {
-  while (!Done() && iter_->second == 0) {
-    ++iter_;
-  }
-}
-
-}  // namespace
-
-SampleMap::SampleMap() : SampleMap(0) {}
-
-SampleMap::SampleMap(uint64_t id) : HistogramSamples(id, new LocalMetadata()) {}
-
-SampleMap::~SampleMap() {
-  delete static_cast<LocalMetadata*>(meta());
-}
-
-void SampleMap::Accumulate(Sample value, Count count) {
-  sample_counts_[value] += count;
-  IncreaseSumAndCount(strict_cast<int64_t>(count) * value, count);
-}
-
-Count SampleMap::GetCount(Sample value) const {
-  std::map<Sample, Count>::const_iterator it = sample_counts_.find(value);
-  if (it == sample_counts_.end())
-    return 0;
-  return it->second;
-}
-
-Count SampleMap::TotalCount() const {
-  Count count = 0;
-  for (const auto& entry : sample_counts_) {
-    count += entry.second;
-  }
-  return count;
-}
-
-std::unique_ptr<SampleCountIterator> SampleMap::Iterator() const {
-  return WrapUnique(new SampleMapIterator(sample_counts_));
-}
-
-bool SampleMap::AddSubtractImpl(SampleCountIterator* iter, Operator op) {
-  Sample min;
-  int64_t max;
-  Count count;
-  for (; !iter->Done(); iter->Next()) {
-    iter->Get(&min, &max, &count);
-    if (strict_cast<int64_t>(min) + 1 != max)
-      return false;  // SparseHistogram only supports bucket with size 1.
-
-    sample_counts_[min] += (op == HistogramSamples::ADD) ? count : -count;
-  }
-  return true;
-}
-
-}  // namespace base
diff --git a/base/metrics/sample_map.h b/base/metrics/sample_map.h
deleted file mode 100644
index 7458e05..0000000
--- a/base/metrics/sample_map.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// SampleMap implements HistogramSamples interface. It is used by the
-// SparseHistogram class to store samples.
-
-#ifndef BASE_METRICS_SAMPLE_MAP_H_
-#define BASE_METRICS_SAMPLE_MAP_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-
-#include "base/compiler_specific.h"
-#include "base/macros.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_samples.h"
-
-namespace base {
-
-// The logic here is similar to that of PersistentSampleMap but with different
-// data structures. Changes here likely need to be duplicated there.
-class BASE_EXPORT SampleMap : public HistogramSamples {
- public:
-  SampleMap();
-  explicit SampleMap(uint64_t id);
-  ~SampleMap() override;
-
-  // HistogramSamples:
-  void Accumulate(HistogramBase::Sample value,
-                  HistogramBase::Count count) override;
-  HistogramBase::Count GetCount(HistogramBase::Sample value) const override;
-  HistogramBase::Count TotalCount() const override;
-  std::unique_ptr<SampleCountIterator> Iterator() const override;
-
- protected:
-  // Performs arithemetic. |op| is ADD or SUBTRACT.
-  bool AddSubtractImpl(SampleCountIterator* iter, Operator op) override;
-
- private:
-  std::map<HistogramBase::Sample, HistogramBase::Count> sample_counts_;
-
-  DISALLOW_COPY_AND_ASSIGN(SampleMap);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_SAMPLE_MAP_H_
diff --git a/base/metrics/sample_vector.cc b/base/metrics/sample_vector.cc
deleted file mode 100644
index cf8634e..0000000
--- a/base/metrics/sample_vector.cc
+++ /dev/null
@@ -1,429 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/sample_vector.h"
-
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/persistent_memory_allocator.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/platform_thread.h"
-
-// This SampleVector makes use of the single-sample embedded in the base
-// HistogramSamples class. If the count is non-zero then there is guaranteed
-// (within the bounds of "eventual consistency") to be no allocated external
-// storage. Once the full counts storage is allocated, the single-sample must
-// be extracted and disabled.
-
-namespace base {
-
-typedef HistogramBase::Count Count;
-typedef HistogramBase::Sample Sample;
-
-SampleVectorBase::SampleVectorBase(uint64_t id,
-                                   Metadata* meta,
-                                   const BucketRanges* bucket_ranges)
-    : HistogramSamples(id, meta), bucket_ranges_(bucket_ranges) {
-  CHECK_GE(bucket_ranges_->bucket_count(), 1u);
-}
-
-SampleVectorBase::~SampleVectorBase() = default;
-
-void SampleVectorBase::Accumulate(Sample value, Count count) {
-  const size_t bucket_index = GetBucketIndex(value);
-
-  // Handle the single-sample case.
-  if (!counts()) {
-    // Try to accumulate the parameters into the single-count entry.
-    if (AccumulateSingleSample(value, count, bucket_index)) {
-      // A race condition could lead to a new single-sample being accumulated
-      // above just after another thread executed the MountCountsStorage below.
-      // Since it is mounted, it could be mounted elsewhere and have values
-      // written to it. It's not allowed to have both a single-sample and
-      // entries in the counts array so move the single-sample.
-      if (counts())
-        MoveSingleSampleToCounts();
-      return;
-    }
-
-    // Need real storage to store both what was in the single-sample plus the
-    // parameter information.
-    MountCountsStorageAndMoveSingleSample();
-  }
-
-  // Handle the multi-sample case.
-  Count new_value =
-      subtle::NoBarrier_AtomicIncrement(&counts()[bucket_index], count);
-  IncreaseSumAndCount(strict_cast<int64_t>(count) * value, count);
-
-  // TODO(bcwhite) Remove after crbug.com/682680.
-  Count old_value = new_value - count;
-  if ((new_value >= 0) != (old_value >= 0) && count > 0)
-    RecordNegativeSample(SAMPLES_ACCUMULATE_OVERFLOW, count);
-}
-
-Count SampleVectorBase::GetCount(Sample value) const {
-  return GetCountAtIndex(GetBucketIndex(value));
-}
-
-Count SampleVectorBase::TotalCount() const {
-  // Handle the single-sample case.
-  SingleSample sample = single_sample().Load();
-  if (sample.count != 0)
-    return sample.count;
-
-  // Handle the multi-sample case.
-  if (counts() || MountExistingCountsStorage()) {
-    Count count = 0;
-    size_t size = counts_size();
-    const HistogramBase::AtomicCount* counts_array = counts();
-    for (size_t i = 0; i < size; ++i) {
-      count += subtle::NoBarrier_Load(&counts_array[i]);
-    }
-    return count;
-  }
-
-  // And the no-value case.
-  return 0;
-}
-
-Count SampleVectorBase::GetCountAtIndex(size_t bucket_index) const {
-  DCHECK(bucket_index < counts_size());
-
-  // Handle the single-sample case.
-  SingleSample sample = single_sample().Load();
-  if (sample.count != 0)
-    return sample.bucket == bucket_index ? sample.count : 0;
-
-  // Handle the multi-sample case.
-  if (counts() || MountExistingCountsStorage())
-    return subtle::NoBarrier_Load(&counts()[bucket_index]);
-
-  // And the no-value case.
-  return 0;
-}
-
-std::unique_ptr<SampleCountIterator> SampleVectorBase::Iterator() const {
-  // Handle the single-sample case.
-  SingleSample sample = single_sample().Load();
-  if (sample.count != 0) {
-    return std::make_unique<SingleSampleIterator>(
-        bucket_ranges_->range(sample.bucket),
-        bucket_ranges_->range(sample.bucket + 1), sample.count, sample.bucket);
-  }
-
-  // Handle the multi-sample case.
-  if (counts() || MountExistingCountsStorage()) {
-    return std::make_unique<SampleVectorIterator>(counts(), counts_size(),
-                                                  bucket_ranges_);
-  }
-
-  // And the no-value case.
-  return std::make_unique<SampleVectorIterator>(nullptr, 0, bucket_ranges_);
-}
-
-bool SampleVectorBase::AddSubtractImpl(SampleCountIterator* iter,
-                                       HistogramSamples::Operator op) {
-  // Stop now if there's nothing to do.
-  if (iter->Done())
-    return true;
-
-  // Get the first value and its index.
-  HistogramBase::Sample min;
-  int64_t max;
-  HistogramBase::Count count;
-  iter->Get(&min, &max, &count);
-  size_t dest_index = GetBucketIndex(min);
-
-  // The destination must be a superset of the source meaning that though the
-  // incoming ranges will find an exact match, the incoming bucket-index, if
-  // it exists, may be offset from the destination bucket-index. Calculate
-  // that offset of the passed iterator; there are are no overflow checks
-  // because 2's compliment math will work it out in the end.
-  //
-  // Because GetBucketIndex() always returns the same true or false result for
-  // a given iterator object, |index_offset| is either set here and used below,
-  // or never set and never used. The compiler doesn't know this, though, which
-  // is why it's necessary to initialize it to something.
-  size_t index_offset = 0;
-  size_t iter_index;
-  if (iter->GetBucketIndex(&iter_index))
-    index_offset = dest_index - iter_index;
-  if (dest_index >= counts_size())
-    return false;
-
-  // Post-increment. Information about the current sample is not available
-  // after this point.
-  iter->Next();
-
-  // Single-value storage is possible if there is no counts storage and the
-  // retrieved entry is the only one in the iterator.
-  if (!counts()) {
-    if (iter->Done()) {
-      // Don't call AccumulateSingleSample because that updates sum and count
-      // which was already done by the caller of this method.
-      if (single_sample().Accumulate(
-              dest_index, op == HistogramSamples::ADD ? count : -count)) {
-        // Handle race-condition that mounted counts storage between above and
-        // here.
-        if (counts())
-          MoveSingleSampleToCounts();
-        return true;
-      }
-    }
-
-    // The counts storage will be needed to hold the multiple incoming values.
-    MountCountsStorageAndMoveSingleSample();
-  }
-
-  // Go through the iterator and add the counts into correct bucket.
-  while (true) {
-    // Ensure that the sample's min/max match the ranges min/max.
-    if (min != bucket_ranges_->range(dest_index) ||
-        max != bucket_ranges_->range(dest_index + 1)) {
-      NOTREACHED() << "sample=" << min << "," << max
-                   << "; range=" << bucket_ranges_->range(dest_index) << ","
-                   << bucket_ranges_->range(dest_index + 1);
-      return false;
-    }
-
-    // Sample's bucket matches exactly. Adjust count.
-    subtle::NoBarrier_AtomicIncrement(
-        &counts()[dest_index], op == HistogramSamples::ADD ? count : -count);
-
-    // Advance to the next iterable sample. See comments above for how
-    // everything works.
-    if (iter->Done())
-      return true;
-    iter->Get(&min, &max, &count);
-    if (iter->GetBucketIndex(&iter_index)) {
-      // Destination bucket is a known offset from the source bucket.
-      dest_index = iter_index + index_offset;
-    } else {
-      // Destination bucket has to be determined anew each time.
-      dest_index = GetBucketIndex(min);
-    }
-    if (dest_index >= counts_size())
-      return false;
-    iter->Next();
-  }
-}
-
-// Use simple binary search.  This is very general, but there are better
-// approaches if we knew that the buckets were linearly distributed.
-size_t SampleVectorBase::GetBucketIndex(Sample value) const {
-  size_t bucket_count = bucket_ranges_->bucket_count();
-  CHECK_GE(bucket_count, 1u);
-  CHECK_GE(value, bucket_ranges_->range(0));
-  CHECK_LT(value, bucket_ranges_->range(bucket_count));
-
-  size_t under = 0;
-  size_t over = bucket_count;
-  size_t mid;
-  do {
-    DCHECK_GE(over, under);
-    mid = under + (over - under)/2;
-    if (mid == under)
-      break;
-    if (bucket_ranges_->range(mid) <= value)
-      under = mid;
-    else
-      over = mid;
-  } while (true);
-
-  DCHECK_LE(bucket_ranges_->range(mid), value);
-  CHECK_GT(bucket_ranges_->range(mid + 1), value);
-  return mid;
-}
-
-void SampleVectorBase::MoveSingleSampleToCounts() {
-  DCHECK(counts());
-
-  // Disable the single-sample since there is now counts storage for the data.
-  SingleSample sample = single_sample().Extract(/*disable=*/true);
-
-  // Stop here if there is no "count" as trying to find the bucket index of
-  // an invalid (including zero) "value" will crash.
-  if (sample.count == 0)
-    return;
-
-  // Move the value into storage. Sum and redundant-count already account
-  // for this entry so no need to call IncreaseSumAndCount().
-  subtle::NoBarrier_AtomicIncrement(&counts()[sample.bucket], sample.count);
-}
-
-void SampleVectorBase::MountCountsStorageAndMoveSingleSample() {
-  // There are many SampleVector objects and the lock is needed very
-  // infrequently (just when advancing from single-sample to multi-sample) so
-  // define a single, global lock that all can use. This lock only prevents
-  // concurrent entry into the code below; access and updates to |counts_|
-  // still requires atomic operations.
-  static LazyInstance<Lock>::Leaky counts_lock = LAZY_INSTANCE_INITIALIZER;
-  if (subtle::NoBarrier_Load(&counts_) == 0) {
-    AutoLock lock(counts_lock.Get());
-    if (subtle::NoBarrier_Load(&counts_) == 0) {
-      // Create the actual counts storage while the above lock is acquired.
-      HistogramBase::Count* counts = CreateCountsStorageWhileLocked();
-      DCHECK(counts);
-
-      // Point |counts_| to the newly created storage. This is done while
-      // locked to prevent possible concurrent calls to CreateCountsStorage
-      // but, between that call and here, other threads could notice the
-      // existence of the storage and race with this to set_counts(). That's
-      // okay because (a) it's atomic and (b) it always writes the same value.
-      set_counts(counts);
-    }
-  }
-
-  // Move any single-sample into the newly mounted storage.
-  MoveSingleSampleToCounts();
-}
-
-SampleVector::SampleVector(const BucketRanges* bucket_ranges)
-    : SampleVector(0, bucket_ranges) {}
-
-SampleVector::SampleVector(uint64_t id, const BucketRanges* bucket_ranges)
-    : SampleVectorBase(id, new LocalMetadata(), bucket_ranges) {}
-
-SampleVector::~SampleVector() {
-  delete static_cast<LocalMetadata*>(meta());
-}
-
-bool SampleVector::MountExistingCountsStorage() const {
-  // There is never any existing storage other than what is already in use.
-  return counts() != nullptr;
-}
-
-HistogramBase::AtomicCount* SampleVector::CreateCountsStorageWhileLocked() {
-  local_counts_.resize(counts_size());
-  return &local_counts_[0];
-}
-
-PersistentSampleVector::PersistentSampleVector(
-    uint64_t id,
-    const BucketRanges* bucket_ranges,
-    Metadata* meta,
-    const DelayedPersistentAllocation& counts)
-    : SampleVectorBase(id, meta, bucket_ranges), persistent_counts_(counts) {
-  // Only mount the full storage if the single-sample has been disabled.
-  // Otherwise, it is possible for this object instance to start using (empty)
-  // storage that was created incidentally while another instance continues to
-  // update to the single sample. This "incidental creation" can happen because
-  // the memory is a DelayedPersistentAllocation which allows multiple memory
-  // blocks within it and applies an all-or-nothing approach to the allocation.
-  // Thus, a request elsewhere for one of the _other_ blocks would make _this_
-  // block available even though nothing has explicitly requested it.
-  //
-  // Note that it's not possible for the ctor to mount existing storage and
-  // move any single-sample to it because sometimes the persistent memory is
-  // read-only. Only non-const methods (which assume that memory is read/write)
-  // can do that.
-  if (single_sample().IsDisabled()) {
-    bool success = MountExistingCountsStorage();
-    DCHECK(success);
-  }
-}
-
-PersistentSampleVector::~PersistentSampleVector() = default;
-
-bool PersistentSampleVector::MountExistingCountsStorage() const {
-  // There is no early exit if counts is not yet mounted because, given that
-  // this is a virtual function, it's more efficient to do that at the call-
-  // site. There is no danger, however, should this get called anyway (perhaps
-  // because of a race condition) because at worst the |counts_| value would
-  // be over-written (in an atomic manner) with the exact same address.
-
-  if (!persistent_counts_.reference())
-    return false;  // Nothing to mount.
-
-  // Mount the counts array in position.
-  set_counts(
-      static_cast<HistogramBase::AtomicCount*>(persistent_counts_.Get()));
-
-  // The above shouldn't fail but can if the data is corrupt or incomplete.
-  return counts() != nullptr;
-}
-
-HistogramBase::AtomicCount*
-PersistentSampleVector::CreateCountsStorageWhileLocked() {
-  void* mem = persistent_counts_.Get();
-  if (!mem) {
-    // The above shouldn't fail but can if Bad Things(tm) are occurring in the
-    // persistent allocator. Crashing isn't a good option so instead just
-    // allocate something from the heap and return that. There will be no
-    // sharing or persistence but worse things are already happening.
-    return new HistogramBase::AtomicCount[counts_size()];
-  }
-
-  return static_cast<HistogramBase::AtomicCount*>(mem);
-}
-
-SampleVectorIterator::SampleVectorIterator(
-    const std::vector<HistogramBase::AtomicCount>* counts,
-    const BucketRanges* bucket_ranges)
-    : counts_(&(*counts)[0]),
-      counts_size_(counts->size()),
-      bucket_ranges_(bucket_ranges),
-      index_(0) {
-  DCHECK_GE(bucket_ranges_->bucket_count(), counts_size_);
-  SkipEmptyBuckets();
-}
-
-SampleVectorIterator::SampleVectorIterator(
-    const HistogramBase::AtomicCount* counts,
-    size_t counts_size,
-    const BucketRanges* bucket_ranges)
-    : counts_(counts),
-      counts_size_(counts_size),
-      bucket_ranges_(bucket_ranges),
-      index_(0) {
-  DCHECK_GE(bucket_ranges_->bucket_count(), counts_size_);
-  SkipEmptyBuckets();
-}
-
-SampleVectorIterator::~SampleVectorIterator() = default;
-
-bool SampleVectorIterator::Done() const {
-  return index_ >= counts_size_;
-}
-
-void SampleVectorIterator::Next() {
-  DCHECK(!Done());
-  index_++;
-  SkipEmptyBuckets();
-}
-
-void SampleVectorIterator::Get(HistogramBase::Sample* min,
-                               int64_t* max,
-                               HistogramBase::Count* count) const {
-  DCHECK(!Done());
-  if (min != nullptr)
-    *min = bucket_ranges_->range(index_);
-  if (max != nullptr)
-    *max = strict_cast<int64_t>(bucket_ranges_->range(index_ + 1));
-  if (count != nullptr)
-    *count = subtle::NoBarrier_Load(&counts_[index_]);
-}
-
-bool SampleVectorIterator::GetBucketIndex(size_t* index) const {
-  DCHECK(!Done());
-  if (index != nullptr)
-    *index = index_;
-  return true;
-}
-
-void SampleVectorIterator::SkipEmptyBuckets() {
-  if (Done())
-    return;
-
-  while (index_ < counts_size_) {
-    if (subtle::NoBarrier_Load(&counts_[index_]) != 0)
-      return;
-    index_++;
-  }
-}
-
-}  // namespace base
diff --git a/base/metrics/sample_vector.h b/base/metrics/sample_vector.h
deleted file mode 100644
index 278272d..0000000
--- a/base/metrics/sample_vector.h
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// SampleVector implements HistogramSamples interface. It is used by all
-// Histogram based classes to store samples.
-
-#ifndef BASE_METRICS_SAMPLE_VECTOR_H_
-#define BASE_METRICS_SAMPLE_VECTOR_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <memory>
-#include <vector>
-
-#include "base/atomicops.h"
-#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
-#include "base/macros.h"
-#include "base/metrics/bucket_ranges.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/persistent_memory_allocator.h"
-
-namespace base {
-
-class BucketRanges;
-
-class BASE_EXPORT SampleVectorBase : public HistogramSamples {
- public:
-  SampleVectorBase(uint64_t id,
-                   Metadata* meta,
-                   const BucketRanges* bucket_ranges);
-  ~SampleVectorBase() override;
-
-  // HistogramSamples:
-  void Accumulate(HistogramBase::Sample value,
-                  HistogramBase::Count count) override;
-  HistogramBase::Count GetCount(HistogramBase::Sample value) const override;
-  HistogramBase::Count TotalCount() const override;
-  std::unique_ptr<SampleCountIterator> Iterator() const override;
-
-  // Get count of a specific bucket.
-  HistogramBase::Count GetCountAtIndex(size_t bucket_index) const;
-
-  // Access the bucket ranges held externally.
-  const BucketRanges* bucket_ranges() const { return bucket_ranges_; }
-
- protected:
-  bool AddSubtractImpl(
-      SampleCountIterator* iter,
-      HistogramSamples::Operator op) override;  // |op| is ADD or SUBTRACT.
-
-  virtual size_t GetBucketIndex(HistogramBase::Sample value) const;
-
-  // Moves the single-sample value to a mounted "counts" array.
-  void MoveSingleSampleToCounts();
-
-  // Mounts (creating if necessary) an array of "counts" for multi-value
-  // storage.
-  void MountCountsStorageAndMoveSingleSample();
-
-  // Mounts "counts" storage that already exists. This does not attempt to move
-  // any single-sample information to that storage as that would violate the
-  // "const" restriction that is often used to indicate read-only memory.
-  virtual bool MountExistingCountsStorage() const = 0;
-
-  // Creates "counts" storage and returns a pointer to it. Ownership of the
-  // array remains with the called method but will never change. This must be
-  // called while some sort of lock is held to prevent reentry.
-  virtual HistogramBase::Count* CreateCountsStorageWhileLocked() = 0;
-
-  HistogramBase::AtomicCount* counts() {
-    return reinterpret_cast<HistogramBase::AtomicCount*>(
-        subtle::Acquire_Load(&counts_));
-  }
-
-  const HistogramBase::AtomicCount* counts() const {
-    return reinterpret_cast<HistogramBase::AtomicCount*>(
-        subtle::Acquire_Load(&counts_));
-  }
-
-  void set_counts(const HistogramBase::AtomicCount* counts) const {
-    subtle::Release_Store(&counts_, reinterpret_cast<uintptr_t>(counts));
-  }
-
-  size_t counts_size() const { return bucket_ranges_->bucket_count(); }
-
- private:
-  friend class SampleVectorTest;
-  FRIEND_TEST_ALL_PREFIXES(HistogramTest, CorruptSampleCounts);
-  FRIEND_TEST_ALL_PREFIXES(SharedHistogramTest, CorruptSampleCounts);
-
-  // |counts_| is actually a pointer to a HistogramBase::AtomicCount array but
-  // is held as an AtomicWord for concurrency reasons. When combined with the
-  // single_sample held in the metadata, there are four possible states:
-  //   1) single_sample == zero, counts_ == null
-  //   2) single_sample != zero, counts_ == null
-  //   3) single_sample != zero, counts_ != null BUT IS EMPTY
-  //   4) single_sample == zero, counts_ != null and may have data
-  // Once |counts_| is set, it can never revert and any existing single-sample
-  // must be moved to this storage. It is mutable because changing it doesn't
-  // change the (const) data but must adapt if a non-const object causes the
-  // storage to be allocated and updated.
-  mutable subtle::AtomicWord counts_ = 0;
-
-  // Shares the same BucketRanges with Histogram object.
-  const BucketRanges* const bucket_ranges_;
-
-  DISALLOW_COPY_AND_ASSIGN(SampleVectorBase);
-};
-
-// A sample vector that uses local memory for the counts array.
-class BASE_EXPORT SampleVector : public SampleVectorBase {
- public:
-  explicit SampleVector(const BucketRanges* bucket_ranges);
-  SampleVector(uint64_t id, const BucketRanges* bucket_ranges);
-  ~SampleVector() override;
-
- private:
-  // SampleVectorBase:
-  bool MountExistingCountsStorage() const override;
-  HistogramBase::Count* CreateCountsStorageWhileLocked() override;
-
-  // Simple local storage for counts.
-  mutable std::vector<HistogramBase::AtomicCount> local_counts_;
-
-  DISALLOW_COPY_AND_ASSIGN(SampleVector);
-};
-
-// A sample vector that uses persistent memory for the counts array.
-class BASE_EXPORT PersistentSampleVector : public SampleVectorBase {
- public:
-  PersistentSampleVector(uint64_t id,
-                         const BucketRanges* bucket_ranges,
-                         Metadata* meta,
-                         const DelayedPersistentAllocation& counts);
-  ~PersistentSampleVector() override;
-
- private:
-  // SampleVectorBase:
-  bool MountExistingCountsStorage() const override;
-  HistogramBase::Count* CreateCountsStorageWhileLocked() override;
-
-  // Persistent storage for counts.
-  DelayedPersistentAllocation persistent_counts_;
-
-  DISALLOW_COPY_AND_ASSIGN(PersistentSampleVector);
-};
-
-// An iterator for sample vectors. This could be defined privately in the .cc
-// file but is here for easy testing.
-class BASE_EXPORT SampleVectorIterator : public SampleCountIterator {
- public:
-  SampleVectorIterator(const std::vector<HistogramBase::AtomicCount>* counts,
-                       const BucketRanges* bucket_ranges);
-  SampleVectorIterator(const HistogramBase::AtomicCount* counts,
-                       size_t counts_size,
-                       const BucketRanges* bucket_ranges);
-  ~SampleVectorIterator() override;
-
-  // SampleCountIterator implementation:
-  bool Done() const override;
-  void Next() override;
-  void Get(HistogramBase::Sample* min,
-           int64_t* max,
-           HistogramBase::Count* count) const override;
-
-  // SampleVector uses predefined buckets, so iterator can return bucket index.
-  bool GetBucketIndex(size_t* index) const override;
-
- private:
-  void SkipEmptyBuckets();
-
-  const HistogramBase::AtomicCount* counts_;
-  size_t counts_size_;
-  const BucketRanges* bucket_ranges_;
-
-  size_t index_;
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_SAMPLE_VECTOR_H_
diff --git a/base/metrics/single_sample_metrics.cc b/base/metrics/single_sample_metrics.cc
deleted file mode 100644
index 57c1c8f..0000000
--- a/base/metrics/single_sample_metrics.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/single_sample_metrics.h"
-
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram.h"
-
-namespace base {
-
-static SingleSampleMetricsFactory* g_factory = nullptr;
-
-// static
-SingleSampleMetricsFactory* SingleSampleMetricsFactory::Get() {
-  if (!g_factory)
-    g_factory = new DefaultSingleSampleMetricsFactory();
-
-  return g_factory;
-}
-
-// static
-void SingleSampleMetricsFactory::SetFactory(
-    std::unique_ptr<SingleSampleMetricsFactory> factory) {
-  DCHECK(!g_factory);
-  g_factory = factory.release();
-}
-
-// static
-void SingleSampleMetricsFactory::DeleteFactoryForTesting() {
-  DCHECK(g_factory);
-  delete g_factory;
-  g_factory = nullptr;
-}
-
-std::unique_ptr<SingleSampleMetric>
-DefaultSingleSampleMetricsFactory::CreateCustomCountsMetric(
-    const std::string& histogram_name,
-    HistogramBase::Sample min,
-    HistogramBase::Sample max,
-    uint32_t bucket_count) {
-  return std::make_unique<DefaultSingleSampleMetric>(
-      histogram_name, min, max, bucket_count,
-      HistogramBase::kUmaTargetedHistogramFlag);
-}
-
-DefaultSingleSampleMetric::DefaultSingleSampleMetric(
-    const std::string& histogram_name,
-    HistogramBase::Sample min,
-    HistogramBase::Sample max,
-    uint32_t bucket_count,
-    int32_t flags)
-    : histogram_(Histogram::FactoryGet(histogram_name,
-                                       min,
-                                       max,
-                                       bucket_count,
-                                       flags)) {
-  // Bad construction parameters may lead to |histogram_| being null; DCHECK to
-  // find accidental errors in production. We must still handle the nullptr in
-  // destruction though since this construction may come from another untrusted
-  // process.
-  DCHECK(histogram_);
-}
-
-DefaultSingleSampleMetric::~DefaultSingleSampleMetric() {
-  // |histogram_| may be nullptr if bad construction parameters are given.
-  if (sample_ < 0 || !histogram_)
-    return;
-  histogram_->Add(sample_);
-}
-
-void DefaultSingleSampleMetric::SetSample(HistogramBase::Sample sample) {
-  DCHECK_GE(sample, 0);
-  sample_ = sample;
-}
-
-}  // namespace base
diff --git a/base/metrics/single_sample_metrics.h b/base/metrics/single_sample_metrics.h
deleted file mode 100644
index b966cb1..0000000
--- a/base/metrics/single_sample_metrics.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_SINGLE_SAMPLE_METRICS_H_
-#define BASE_METRICS_SINGLE_SAMPLE_METRICS_H_
-
-#include <string>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/metrics/histogram_base.h"
-
-namespace base {
-
-// See base/metrics/histograms.h for parameter definitions. Must only be used
-// and destroyed from the same thread as construction.
-class BASE_EXPORT SingleSampleMetric {
- public:
-  virtual ~SingleSampleMetric() = default;
-
-  virtual void SetSample(HistogramBase::Sample sample) = 0;
-};
-
-// Factory for creating single sample metrics. A single sample metric only
-// reports its sample once at destruction time. The sample may be changed prior
-// to destruction using the SetSample() method as many times as desired.
-//
-// The metric creation methods are safe to call from any thread, however the
-// returned class must only be used and destroyed from the same thread as
-// construction.
-//
-// See base/metrics/histogram_macros.h for usage recommendations and
-// base/metrics/histogram.h for full parameter definitions.
-class BASE_EXPORT SingleSampleMetricsFactory {
- public:
-  virtual ~SingleSampleMetricsFactory() = default;
-
-  // Returns the factory provided by SetFactory(), or if no factory has been set
-  // a default factory will be provided (future calls to SetFactory() will fail
-  // if the default factory is ever vended).
-  static SingleSampleMetricsFactory* Get();
-  static void SetFactory(std::unique_ptr<SingleSampleMetricsFactory> factory);
-
-  // The factory normally persists until process shutdown, but in testing we
-  // should avoid leaking it since it sets a global.
-  static void DeleteFactoryForTesting();
-
-  // The methods below return a single sample metric for counts histograms; see
-  // method comments for the corresponding histogram macro.
-
-  // UMA_HISTOGRAM_CUSTOM_COUNTS()
-  virtual std::unique_ptr<SingleSampleMetric> CreateCustomCountsMetric(
-      const std::string& histogram_name,
-      HistogramBase::Sample min,
-      HistogramBase::Sample max,
-      uint32_t bucket_count) = 0;
-};
-
-// Default implementation for when no factory has been provided to the process.
-// Samples are only recorded within the current process in this case, so samples
-// will be lost in the event of sudden process termination.
-class BASE_EXPORT DefaultSingleSampleMetricsFactory
-    : public SingleSampleMetricsFactory {
- public:
-  DefaultSingleSampleMetricsFactory() = default;
-  ~DefaultSingleSampleMetricsFactory() override = default;
-
-  // SingleSampleMetricsFactory:
-  std::unique_ptr<SingleSampleMetric> CreateCustomCountsMetric(
-      const std::string& histogram_name,
-      HistogramBase::Sample min,
-      HistogramBase::Sample max,
-      uint32_t bucket_count) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DefaultSingleSampleMetricsFactory);
-};
-
-class BASE_EXPORT DefaultSingleSampleMetric : public SingleSampleMetric {
- public:
-  DefaultSingleSampleMetric(const std::string& histogram_name,
-                            HistogramBase::Sample min,
-                            HistogramBase::Sample max,
-                            uint32_t bucket_count,
-                            int32_t flags);
-  ~DefaultSingleSampleMetric() override;
-
-  // SingleSampleMetric:
-  void SetSample(HistogramBase::Sample sample) override;
-
- private:
-  HistogramBase* const histogram_;
-
-  // The last sample provided to SetSample(). We use -1 as a sentinel value to
-  // indicate no sample has been set.
-  HistogramBase::Sample sample_ = -1;
-
-  DISALLOW_COPY_AND_ASSIGN(DefaultSingleSampleMetric);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_SINGLE_SAMPLE_METRICS_H_
diff --git a/base/metrics/sparse_histogram.cc b/base/metrics/sparse_histogram.cc
deleted file mode 100644
index 30175a0..0000000
--- a/base/metrics/sparse_histogram.cc
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/sparse_histogram.h"
-
-#include <utility>
-
-#include "base/memory/ptr_util.h"
-#include "base/metrics/dummy_histogram.h"
-#include "base/metrics/metrics_hashes.h"
-#include "base/metrics/persistent_histogram_allocator.h"
-#include "base/metrics/persistent_sample_map.h"
-#include "base/metrics/sample_map.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/pickle.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-typedef HistogramBase::Count Count;
-typedef HistogramBase::Sample Sample;
-
-// static
-HistogramBase* SparseHistogram::FactoryGet(const std::string& name,
-                                           int32_t flags) {
-  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
-  if (!histogram) {
-    // TODO(gayane): |HashMetricName| is called again in Histogram constructor.
-    // Refactor code to avoid the additional call.
-    bool should_record =
-        StatisticsRecorder::ShouldRecordHistogram(HashMetricName(name));
-    if (!should_record)
-      return DummyHistogram::GetInstance();
-    // Try to create the histogram using a "persistent" allocator. As of
-    // 2016-02-25, the availability of such is controlled by a base::Feature
-    // that is off by default. If the allocator doesn't exist or if
-    // allocating from it fails, code below will allocate the histogram from
-    // the process heap.
-    PersistentMemoryAllocator::Reference histogram_ref = 0;
-    std::unique_ptr<HistogramBase> tentative_histogram;
-    PersistentHistogramAllocator* allocator = GlobalHistogramAllocator::Get();
-    if (allocator) {
-      tentative_histogram = allocator->AllocateHistogram(
-          SPARSE_HISTOGRAM, name, 0, 0, nullptr, flags, &histogram_ref);
-    }
-
-    // Handle the case where no persistent allocator is present or the
-    // persistent allocation fails (perhaps because it is full).
-    if (!tentative_histogram) {
-      DCHECK(!histogram_ref);  // Should never have been set.
-      DCHECK(!allocator);      // Shouldn't have failed.
-      flags &= ~HistogramBase::kIsPersistent;
-      tentative_histogram.reset(new SparseHistogram(GetPermanentName(name)));
-      tentative_histogram->SetFlags(flags);
-    }
-
-    // Register this histogram with the StatisticsRecorder. Keep a copy of
-    // the pointer value to tell later whether the locally created histogram
-    // was registered or deleted. The type is "void" because it could point
-    // to released memory after the following line.
-    const void* tentative_histogram_ptr = tentative_histogram.get();
-    histogram = StatisticsRecorder::RegisterOrDeleteDuplicate(
-        tentative_histogram.release());
-
-    // Persistent histograms need some follow-up processing.
-    if (histogram_ref) {
-      allocator->FinalizeHistogram(histogram_ref,
-                                   histogram == tentative_histogram_ptr);
-    }
-  }
-
-  CHECK_EQ(SPARSE_HISTOGRAM, histogram->GetHistogramType());
-  return histogram;
-}
-
-// static
-std::unique_ptr<HistogramBase> SparseHistogram::PersistentCreate(
-    PersistentHistogramAllocator* allocator,
-    const char* name,
-    HistogramSamples::Metadata* meta,
-    HistogramSamples::Metadata* logged_meta) {
-  return WrapUnique(
-      new SparseHistogram(allocator, name, meta, logged_meta));
-}
-
-SparseHistogram::~SparseHistogram() = default;
-
-uint64_t SparseHistogram::name_hash() const {
-  return unlogged_samples_->id();
-}
-
-HistogramType SparseHistogram::GetHistogramType() const {
-  return SPARSE_HISTOGRAM;
-}
-
-bool SparseHistogram::HasConstructionArguments(
-    Sample expected_minimum,
-    Sample expected_maximum,
-    uint32_t expected_bucket_count) const {
-  // SparseHistogram never has min/max/bucket_count limit.
-  return false;
-}
-
-void SparseHistogram::Add(Sample value) {
-  AddCount(value, 1);
-}
-
-void SparseHistogram::AddCount(Sample value, int count) {
-  if (count <= 0) {
-    NOTREACHED();
-    return;
-  }
-  {
-    base::AutoLock auto_lock(lock_);
-    unlogged_samples_->Accumulate(value, count);
-  }
-
-  FindAndRunCallback(value);
-}
-
-std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotSamples() const {
-  std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash()));
-
-  base::AutoLock auto_lock(lock_);
-  snapshot->Add(*unlogged_samples_);
-  snapshot->Add(*logged_samples_);
-  return std::move(snapshot);
-}
-
-std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotDelta() {
-  DCHECK(!final_delta_created_);
-
-  std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash()));
-  base::AutoLock auto_lock(lock_);
-  snapshot->Add(*unlogged_samples_);
-
-  unlogged_samples_->Subtract(*snapshot);
-  logged_samples_->Add(*snapshot);
-  return std::move(snapshot);
-}
-
-std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotFinalDelta() const {
-  DCHECK(!final_delta_created_);
-  final_delta_created_ = true;
-
-  std::unique_ptr<SampleMap> snapshot(new SampleMap(name_hash()));
-  base::AutoLock auto_lock(lock_);
-  snapshot->Add(*unlogged_samples_);
-
-  return std::move(snapshot);
-}
-
-void SparseHistogram::AddSamples(const HistogramSamples& samples) {
-  base::AutoLock auto_lock(lock_);
-  unlogged_samples_->Add(samples);
-}
-
-bool SparseHistogram::AddSamplesFromPickle(PickleIterator* iter) {
-  base::AutoLock auto_lock(lock_);
-  return unlogged_samples_->AddFromPickle(iter);
-}
-
-void SparseHistogram::WriteHTMLGraph(std::string* output) const {
-  output->append("<PRE>");
-  WriteAsciiImpl(true, "<br>", output);
-  output->append("</PRE>");
-}
-
-void SparseHistogram::WriteAscii(std::string* output) const {
-  WriteAsciiImpl(true, "\n", output);
-}
-
-void SparseHistogram::SerializeInfoImpl(Pickle* pickle) const {
-  pickle->WriteString(histogram_name());
-  pickle->WriteInt(flags());
-}
-
-SparseHistogram::SparseHistogram(const char* name)
-    : HistogramBase(name),
-      unlogged_samples_(new SampleMap(HashMetricName(name))),
-      logged_samples_(new SampleMap(unlogged_samples_->id())) {}
-
-SparseHistogram::SparseHistogram(PersistentHistogramAllocator* allocator,
-                                 const char* name,
-                                 HistogramSamples::Metadata* meta,
-                                 HistogramSamples::Metadata* logged_meta)
-    : HistogramBase(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
-      // have no such initial allocation. Each sample has its own record
-      // attached to a single PersistentSampleMap by a common 64-bit identifier.
-      // Since a sparse histogram has two sample maps (active and logged),
-      // there must be two sets of sample records with diffent IDs. The
-      // "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)),
-      logged_samples_(new PersistentSampleMap(unlogged_samples_->id() + 1,
-                                              allocator,
-                                              logged_meta)) {}
-
-HistogramBase* SparseHistogram::DeserializeInfoImpl(PickleIterator* iter) {
-  std::string histogram_name;
-  int flags;
-  if (!iter->ReadString(&histogram_name) || !iter->ReadInt(&flags)) {
-    DLOG(ERROR) << "Pickle error decoding Histogram: " << histogram_name;
-    return nullptr;
-  }
-
-  flags &= ~HistogramBase::kIPCSerializationSourceFlag;
-
-  return SparseHistogram::FactoryGet(histogram_name, flags);
-}
-
-void SparseHistogram::GetParameters(DictionaryValue* params) const {
-  // TODO(kaiwang): Implement. (See HistogramBase::WriteJSON.)
-}
-
-void SparseHistogram::GetCountAndBucketData(Count* count,
-                                            int64_t* sum,
-                                            ListValue* buckets) const {
-  // TODO(kaiwang): Implement. (See HistogramBase::WriteJSON.)
-}
-
-void SparseHistogram::WriteAsciiImpl(bool graph_it,
-                                     const std::string& newline,
-                                     std::string* output) const {
-  // Get a local copy of the data so we are consistent.
-  std::unique_ptr<HistogramSamples> snapshot = SnapshotSamples();
-  Count total_count = snapshot->TotalCount();
-  double scaled_total_count = total_count / 100.0;
-
-  WriteAsciiHeader(total_count, output);
-  output->append(newline);
-
-  // Determine how wide the largest bucket range is (how many digits to print),
-  // so that we'll be able to right-align starts for the graphical bars.
-  // Determine which bucket has the largest sample count so that we can
-  // normalize the graphical bar-width relative to that sample count.
-  Count largest_count = 0;
-  Sample largest_sample = 0;
-  std::unique_ptr<SampleCountIterator> it = snapshot->Iterator();
-  while (!it->Done()) {
-    Sample min;
-    int64_t max;
-    Count count;
-    it->Get(&min, &max, &count);
-    if (min > largest_sample)
-      largest_sample = min;
-    if (count > largest_count)
-      largest_count = count;
-    it->Next();
-  }
-  size_t print_width = GetSimpleAsciiBucketRange(largest_sample).size() + 1;
-
-  // iterate over each item and display them
-  it = snapshot->Iterator();
-  while (!it->Done()) {
-    Sample min;
-    int64_t max;
-    Count count;
-    it->Get(&min, &max, &count);
-
-    // value is min, so display it
-    std::string range = GetSimpleAsciiBucketRange(min);
-    output->append(range);
-    for (size_t j = 0; range.size() + j < print_width + 1; ++j)
-      output->push_back(' ');
-
-    if (graph_it)
-      WriteAsciiBucketGraph(count, largest_count, output);
-    WriteAsciiBucketValue(count, scaled_total_count, output);
-    output->append(newline);
-    it->Next();
-  }
-}
-
-void SparseHistogram::WriteAsciiHeader(const Count total_count,
-                                       std::string* output) const {
-  StringAppendF(output, "Histogram: %s recorded %d samples", histogram_name(),
-                total_count);
-  if (flags())
-    StringAppendF(output, " (flags = 0x%x)", flags());
-}
-
-}  // namespace base
diff --git a/base/metrics/sparse_histogram.h b/base/metrics/sparse_histogram.h
deleted file mode 100644
index 913762c..0000000
--- a/base/metrics/sparse_histogram.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_SPARSE_HISTOGRAM_H_
-#define BASE_METRICS_SPARSE_HISTOGRAM_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-#include <string>
-
-#include "base/base_export.h"
-#include "base/macros.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-class HistogramSamples;
-class PersistentHistogramAllocator;
-class Pickle;
-class PickleIterator;
-
-class BASE_EXPORT SparseHistogram : public HistogramBase {
- public:
-  // If there's one with same name, return the existing one. If not, create a
-  // new one.
-  static HistogramBase* FactoryGet(const std::string& name, int32_t flags);
-
-  // Create a histogram using data in persistent storage. The allocator must
-  // live longer than the created sparse histogram.
-  static std::unique_ptr<HistogramBase> PersistentCreate(
-      PersistentHistogramAllocator* allocator,
-      const char* name,
-      HistogramSamples::Metadata* meta,
-      HistogramSamples::Metadata* logged_meta);
-
-  ~SparseHistogram() override;
-
-  // HistogramBase implementation:
-  uint64_t name_hash() const override;
-  HistogramType GetHistogramType() const override;
-  bool HasConstructionArguments(Sample expected_minimum,
-                                Sample expected_maximum,
-                                uint32_t expected_bucket_count) const override;
-  void Add(Sample value) override;
-  void AddCount(Sample value, int count) override;
-  void AddSamples(const HistogramSamples& samples) override;
-  bool AddSamplesFromPickle(base::PickleIterator* iter) override;
-  std::unique_ptr<HistogramSamples> SnapshotSamples() const override;
-  std::unique_ptr<HistogramSamples> SnapshotDelta() override;
-  std::unique_ptr<HistogramSamples> SnapshotFinalDelta() const override;
-  void WriteHTMLGraph(std::string* output) const override;
-  void WriteAscii(std::string* output) const override;
-
- protected:
-  // HistogramBase implementation:
-  void SerializeInfoImpl(base::Pickle* pickle) const override;
-
- private:
-  // Clients should always use FactoryGet to create SparseHistogram.
-  explicit SparseHistogram(const char* name);
-
-  SparseHistogram(PersistentHistogramAllocator* allocator,
-                  const char* name,
-                  HistogramSamples::Metadata* meta,
-                  HistogramSamples::Metadata* logged_meta);
-
-  friend BASE_EXPORT HistogramBase* DeserializeHistogramInfo(
-      base::PickleIterator* iter);
-  static HistogramBase* DeserializeInfoImpl(base::PickleIterator* iter);
-
-  void GetParameters(DictionaryValue* params) const override;
-  void GetCountAndBucketData(Count* count,
-                             int64_t* sum,
-                             ListValue* buckets) const override;
-
-  // Helpers for emitting Ascii graphic.  Each method appends data to output.
-  void WriteAsciiImpl(bool graph_it,
-                      const std::string& newline,
-                      std::string* output) const;
-
-  // Write a common header message describing this histogram.
-  void WriteAsciiHeader(const Count total_count,
-                        std::string* output) const;
-
-  // For constuctor calling.
-  friend class SparseHistogramTest;
-
-  // Protects access to |samples_|.
-  mutable base::Lock lock_;
-
-  // Flag to indicate if PrepareFinalDelta has been previously called.
-  mutable bool final_delta_created_ = false;
-
-  std::unique_ptr<HistogramSamples> unlogged_samples_;
-  std::unique_ptr<HistogramSamples> logged_samples_;
-
-  DISALLOW_COPY_AND_ASSIGN(SparseHistogram);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_SPARSE_HISTOGRAM_H_
diff --git a/base/metrics/statistics_recorder.cc b/base/metrics/statistics_recorder.cc
deleted file mode 100644
index 28773a1..0000000
--- a/base/metrics/statistics_recorder.cc
+++ /dev/null
@@ -1,416 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/statistics_recorder.h"
-
-#include <memory>
-
-#include "base/at_exit.h"
-#include "base/debug/leak_annotations.h"
-#include "base/json/string_escape.h"
-#include "base/logging.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_snapshot_manager.h"
-#include "base/metrics/metrics_hashes.h"
-#include "base/metrics/persistent_histogram_allocator.h"
-#include "base/metrics/record_histogram_checker.h"
-#include "base/stl_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/values.h"
-
-namespace base {
-namespace {
-
-bool HistogramNameLesser(const base::HistogramBase* a,
-                         const base::HistogramBase* b) {
-  return strcmp(a->histogram_name(), b->histogram_name()) < 0;
-}
-
-}  // namespace
-
-// static
-LazyInstance<Lock>::Leaky StatisticsRecorder::lock_;
-
-// static
-StatisticsRecorder* StatisticsRecorder::top_ = nullptr;
-
-// static
-bool StatisticsRecorder::is_vlog_initialized_ = false;
-
-size_t StatisticsRecorder::BucketRangesHash::operator()(
-    const BucketRanges* const a) const {
-  return a->checksum();
-}
-
-bool StatisticsRecorder::BucketRangesEqual::operator()(
-    const BucketRanges* const a,
-    const BucketRanges* const b) const {
-  return a->Equals(b);
-}
-
-StatisticsRecorder::~StatisticsRecorder() {
-  const AutoLock auto_lock(lock_.Get());
-  DCHECK_EQ(this, top_);
-  top_ = previous_;
-}
-
-// static
-void StatisticsRecorder::EnsureGlobalRecorderWhileLocked() {
-  lock_.Get().AssertAcquired();
-  if (top_)
-    return;
-
-  const StatisticsRecorder* const p = new StatisticsRecorder;
-  // The global recorder is never deleted.
-  ANNOTATE_LEAKING_OBJECT_PTR(p);
-  DCHECK_EQ(p, top_);
-}
-
-// static
-void StatisticsRecorder::RegisterHistogramProvider(
-    const WeakPtr<HistogramProvider>& provider) {
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-  top_->providers_.push_back(provider);
-}
-
-// static
-HistogramBase* StatisticsRecorder::RegisterOrDeleteDuplicate(
-    HistogramBase* histogram) {
-  // Declared before |auto_lock| to ensure correct destruction order.
-  std::unique_ptr<HistogramBase> histogram_deleter;
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-
-  const char* const name = histogram->histogram_name();
-  HistogramBase*& registered = top_->histograms_[name];
-
-  if (!registered) {
-    // |name| is guaranteed to never change or be deallocated so long
-    // as the histogram is alive (which is forever).
-    registered = histogram;
-    ANNOTATE_LEAKING_OBJECT_PTR(histogram);  // see crbug.com/79322
-    // If there are callbacks for this histogram, we set the kCallbackExists
-    // flag.
-    const auto callback_iterator = top_->callbacks_.find(name);
-    if (callback_iterator != top_->callbacks_.end()) {
-      if (!callback_iterator->second.is_null())
-        histogram->SetFlags(HistogramBase::kCallbackExists);
-      else
-        histogram->ClearFlags(HistogramBase::kCallbackExists);
-    }
-    return histogram;
-  }
-
-  if (histogram == registered) {
-    // The histogram was registered before.
-    return histogram;
-  }
-
-  // We already have one histogram with this name.
-  histogram_deleter.reset(histogram);
-  return registered;
-}
-
-// static
-const BucketRanges* StatisticsRecorder::RegisterOrDeleteDuplicateRanges(
-    const BucketRanges* ranges) {
-  DCHECK(ranges->HasValidChecksum());
-
-  // Declared before |auto_lock| to ensure correct destruction order.
-  std::unique_ptr<const BucketRanges> ranges_deleter;
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-
-  const BucketRanges* const registered = *top_->ranges_.insert(ranges).first;
-  if (registered == ranges) {
-    ANNOTATE_LEAKING_OBJECT_PTR(ranges);
-  } else {
-    ranges_deleter.reset(ranges);
-  }
-
-  return registered;
-}
-
-// static
-void StatisticsRecorder::WriteHTMLGraph(const std::string& query,
-                                        std::string* output) {
-  for (const HistogramBase* const histogram :
-       Sort(WithName(GetHistograms(), query))) {
-    histogram->WriteHTMLGraph(output);
-    *output += "<br><hr><br>";
-  }
-}
-
-// static
-void StatisticsRecorder::WriteGraph(const std::string& query,
-                                    std::string* output) {
-  if (query.length())
-    StringAppendF(output, "Collections of histograms for %s\n", query.c_str());
-  else
-    output->append("Collections of all histograms\n");
-
-  for (const HistogramBase* const histogram :
-       Sort(WithName(GetHistograms(), query))) {
-    histogram->WriteAscii(output);
-    output->append("\n");
-  }
-}
-
-// static
-std::string StatisticsRecorder::ToJSON(JSONVerbosityLevel verbosity_level) {
-  std::string output = "{\"histograms\":[";
-  const char* sep = "";
-  for (const HistogramBase* const histogram : Sort(GetHistograms())) {
-    output += sep;
-    sep = ",";
-    std::string json;
-    histogram->WriteJSON(&json, verbosity_level);
-    output += json;
-  }
-  output += "]}";
-  return output;
-}
-
-// static
-std::vector<const BucketRanges*> StatisticsRecorder::GetBucketRanges() {
-  std::vector<const BucketRanges*> out;
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-  out.reserve(top_->ranges_.size());
-  out.assign(top_->ranges_.begin(), top_->ranges_.end());
-  return out;
-}
-
-// static
-HistogramBase* StatisticsRecorder::FindHistogram(base::StringPiece name) {
-  // This must be called *before* the lock is acquired below because it will
-  // call back into this object to register histograms. Those called methods
-  // will acquire the lock at that time.
-  ImportGlobalPersistentHistograms();
-
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-
-  const HistogramMap::const_iterator it = top_->histograms_.find(name);
-  return it != top_->histograms_.end() ? it->second : nullptr;
-}
-
-// static
-StatisticsRecorder::HistogramProviders
-StatisticsRecorder::GetHistogramProviders() {
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-  return top_->providers_;
-}
-
-// static
-void StatisticsRecorder::ImportProvidedHistograms() {
-  // Merge histogram data from each provider in turn.
-  for (const WeakPtr<HistogramProvider>& provider : GetHistogramProviders()) {
-    // Weak-pointer may be invalid if the provider was destructed, though they
-    // generally never are.
-    if (provider)
-      provider->MergeHistogramDeltas();
-  }
-}
-
-// static
-void StatisticsRecorder::PrepareDeltas(
-    bool include_persistent,
-    HistogramBase::Flags flags_to_set,
-    HistogramBase::Flags required_flags,
-    HistogramSnapshotManager* snapshot_manager) {
-  Histograms histograms = GetHistograms();
-  if (!include_persistent)
-    histograms = NonPersistent(std::move(histograms));
-  snapshot_manager->PrepareDeltas(Sort(std::move(histograms)), flags_to_set,
-                                  required_flags);
-}
-
-// static
-void StatisticsRecorder::InitLogOnShutdown() {
-  const AutoLock auto_lock(lock_.Get());
-  InitLogOnShutdownWhileLocked();
-}
-
-// static
-bool StatisticsRecorder::SetCallback(
-    const std::string& name,
-    const StatisticsRecorder::OnSampleCallback& cb) {
-  DCHECK(!cb.is_null());
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-
-  if (!top_->callbacks_.insert({name, cb}).second)
-    return false;
-
-  const HistogramMap::const_iterator it = top_->histograms_.find(name);
-  if (it != top_->histograms_.end())
-    it->second->SetFlags(HistogramBase::kCallbackExists);
-
-  return true;
-}
-
-// static
-void StatisticsRecorder::ClearCallback(const std::string& name) {
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-
-  top_->callbacks_.erase(name);
-
-  // We also clear the flag from the histogram (if it exists).
-  const HistogramMap::const_iterator it = top_->histograms_.find(name);
-  if (it != top_->histograms_.end())
-    it->second->ClearFlags(HistogramBase::kCallbackExists);
-}
-
-// static
-StatisticsRecorder::OnSampleCallback StatisticsRecorder::FindCallback(
-    const std::string& name) {
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-  const auto it = top_->callbacks_.find(name);
-  return it != top_->callbacks_.end() ? it->second : OnSampleCallback();
-}
-
-// static
-size_t StatisticsRecorder::GetHistogramCount() {
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-  return top_->histograms_.size();
-}
-
-// static
-void StatisticsRecorder::ForgetHistogramForTesting(base::StringPiece name) {
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-
-  const HistogramMap::iterator found = top_->histograms_.find(name);
-  if (found == top_->histograms_.end())
-    return;
-
-  HistogramBase* const base = found->second;
-  if (base->GetHistogramType() != SPARSE_HISTOGRAM) {
-    // When forgetting a histogram, it's likely that other information is
-    // also becoming invalid. Clear the persistent reference that may no
-    // longer be valid. There's no danger in this as, at worst, duplicates
-    // will be created in persistent memory.
-    static_cast<Histogram*>(base)->bucket_ranges()->set_persistent_reference(0);
-  }
-
-  top_->histograms_.erase(found);
-}
-
-// static
-std::unique_ptr<StatisticsRecorder>
-StatisticsRecorder::CreateTemporaryForTesting() {
-  const AutoLock auto_lock(lock_.Get());
-  return WrapUnique(new StatisticsRecorder());
-}
-
-// static
-void StatisticsRecorder::SetRecordChecker(
-    std::unique_ptr<RecordHistogramChecker> record_checker) {
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-  top_->record_checker_ = std::move(record_checker);
-}
-
-// static
-bool StatisticsRecorder::ShouldRecordHistogram(uint64_t histogram_hash) {
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-  return !top_->record_checker_ ||
-         top_->record_checker_->ShouldRecord(histogram_hash);
-}
-
-// static
-StatisticsRecorder::Histograms StatisticsRecorder::GetHistograms() {
-  // This must be called *before* the lock is acquired below because it will
-  // call back into this object to register histograms. Those called methods
-  // will acquire the lock at that time.
-  ImportGlobalPersistentHistograms();
-
-  Histograms out;
-
-  const AutoLock auto_lock(lock_.Get());
-  EnsureGlobalRecorderWhileLocked();
-
-  out.reserve(top_->histograms_.size());
-  for (const auto& entry : top_->histograms_)
-    out.push_back(entry.second);
-
-  return out;
-}
-
-// static
-StatisticsRecorder::Histograms StatisticsRecorder::Sort(Histograms histograms) {
-  std::sort(histograms.begin(), histograms.end(), &HistogramNameLesser);
-  return histograms;
-}
-
-// static
-StatisticsRecorder::Histograms StatisticsRecorder::WithName(
-    Histograms histograms,
-    const std::string& query) {
-  // Need a C-string query for comparisons against C-string histogram name.
-  const char* const query_string = query.c_str();
-  histograms.erase(std::remove_if(histograms.begin(), histograms.end(),
-                                  [query_string](const HistogramBase* const h) {
-                                    return !strstr(h->histogram_name(),
-                                                   query_string);
-                                  }),
-                   histograms.end());
-  return histograms;
-}
-
-// static
-StatisticsRecorder::Histograms StatisticsRecorder::NonPersistent(
-    Histograms histograms) {
-  histograms.erase(
-      std::remove_if(histograms.begin(), histograms.end(),
-                     [](const HistogramBase* const h) {
-                       return (h->flags() & HistogramBase::kIsPersistent) != 0;
-                     }),
-      histograms.end());
-  return histograms;
-}
-
-// static
-void StatisticsRecorder::ImportGlobalPersistentHistograms() {
-  // Import histograms from known persistent storage. Histograms could have been
-  // added by other processes and they must be fetched and recognized locally.
-  // If the persistent memory segment is not shared between processes, this call
-  // does nothing.
-  if (GlobalHistogramAllocator* allocator = GlobalHistogramAllocator::Get())
-    allocator->ImportHistogramsToStatisticsRecorder();
-}
-
-// This singleton instance should be started during the single threaded portion
-// of main(), and hence it is not thread safe. It initializes globals to provide
-// support for all future calls.
-StatisticsRecorder::StatisticsRecorder() {
-  lock_.Get().AssertAcquired();
-  previous_ = top_;
-  top_ = this;
-  InitLogOnShutdownWhileLocked();
-}
-
-// static
-void StatisticsRecorder::InitLogOnShutdownWhileLocked() {
-  lock_.Get().AssertAcquired();
-  if (!is_vlog_initialized_ && VLOG_IS_ON(1)) {
-    is_vlog_initialized_ = true;
-    const auto dump_to_vlog = [](void*) {
-      std::string output;
-      WriteGraph("", &output);
-      VLOG(1) << output;
-    };
-    AtExitManager::RegisterCallback(dump_to_vlog, nullptr);
-  }
-}
-
-}  // namespace base
diff --git a/base/metrics/statistics_recorder.h b/base/metrics/statistics_recorder.h
deleted file mode 100644
index 87a9311..0000000
--- a/base/metrics/statistics_recorder.h
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// StatisticsRecorder holds all Histograms and BucketRanges that are used by
-// Histograms in the system. It provides a general place for
-// Histograms/BucketRanges to register, and supports a global API for accessing
-// (i.e., dumping, or graphing) the data.
-
-#ifndef BASE_METRICS_STATISTICS_RECORDER_H_
-#define BASE_METRICS_STATISTICS_RECORDER_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/gtest_prod_util.h"
-#include "base/lazy_instance.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/metrics/histogram_base.h"
-#include "base/metrics/record_histogram_checker.h"
-#include "base/strings/string_piece.h"
-#include "base/synchronization/lock.h"
-
-namespace base {
-
-class BucketRanges;
-class HistogramSnapshotManager;
-
-// In-memory recorder of usage statistics (aka metrics, aka histograms).
-//
-// All the public methods are static and act on a global recorder. This global
-// recorder is internally synchronized and all the static methods are thread
-// safe.
-//
-// StatisticsRecorder doesn't have any public constructor. For testing purpose,
-// you can create a temporary recorder using the factory method
-// CreateTemporaryForTesting(). This temporary recorder becomes the global one
-// until deleted. When this temporary recorder is deleted, it restores the
-// previous global one.
-class BASE_EXPORT StatisticsRecorder {
- public:
-  // An interface class that allows the StatisticsRecorder to forcibly merge
-  // histograms from providers when necessary.
-  class HistogramProvider {
-   public:
-    // Merges all histogram information into the global versions.
-    virtual void MergeHistogramDeltas() = 0;
-  };
-
-  typedef std::vector<HistogramBase*> Histograms;
-
-  // Restores the previous global recorder.
-  //
-  // When several temporary recorders are created using
-  // CreateTemporaryForTesting(), these recorders must be deleted in reverse
-  // order of creation.
-  //
-  // This method is thread safe.
-  //
-  // Precondition: The recorder being deleted is the current global recorder.
-  ~StatisticsRecorder();
-
-  // Registers a provider of histograms that can be called to merge those into
-  // the global recorder. Calls to ImportProvidedHistograms() will fetch from
-  // registered providers.
-  //
-  // This method is thread safe.
-  static void RegisterHistogramProvider(
-      const WeakPtr<HistogramProvider>& provider);
-
-  // Registers or adds a new histogram to the collection of statistics. If an
-  // identically named histogram is already registered, then the argument
-  // |histogram| will be deleted. The returned value is always the registered
-  // histogram (either the argument, or the pre-existing registered histogram).
-  //
-  // This method is thread safe.
-  static HistogramBase* RegisterOrDeleteDuplicate(HistogramBase* histogram);
-
-  // Registers or adds a new BucketRanges. If an equivalent BucketRanges is
-  // already registered, then the argument |ranges| will be deleted. The
-  // returned value is always the registered BucketRanges (either the argument,
-  // or the pre-existing one).
-  //
-  // This method is thread safe.
-  static const BucketRanges* RegisterOrDeleteDuplicateRanges(
-      const BucketRanges* ranges);
-
-  // Methods for appending histogram data to a string.  Only histograms which
-  // have |query| as a substring are written to |output| (an empty string will
-  // process all registered histograms).
-  //
-  // These methods are thread safe.
-  static void WriteHTMLGraph(const std::string& query, std::string* output);
-  static void WriteGraph(const std::string& query, std::string* output);
-
-  // Returns the histograms with |verbosity_level| as the serialization
-  // verbosity.
-  //
-  // This method is thread safe.
-  static std::string ToJSON(JSONVerbosityLevel verbosity_level);
-
-  // Gets existing histograms.
-  //
-  // The order of returned histograms is not guaranteed.
-  //
-  // Ownership of the individual histograms remains with the StatisticsRecorder.
-  //
-  // This method is thread safe.
-  static Histograms GetHistograms();
-
-  // Gets BucketRanges used by all histograms registered. The order of returned
-  // BucketRanges is not guaranteed.
-  //
-  // This method is thread safe.
-  static std::vector<const BucketRanges*> GetBucketRanges();
-
-  // Finds a histogram by name. Matches the exact name. Returns a null pointer
-  // if a matching histogram is not found.
-  //
-  // This method is thread safe.
-  static HistogramBase* FindHistogram(base::StringPiece name);
-
-  // Imports histograms from providers.
-  //
-  // This method must be called on the UI thread.
-  static void ImportProvidedHistograms();
-
-  // Snapshots all histograms via |snapshot_manager|. |flags_to_set| is used to
-  // set flags for each histogram. |required_flags| is used to select
-  // histograms to be recorded. Only histograms that have all the flags
-  // specified by the argument will be chosen. If all histograms should be
-  // recorded, set it to |Histogram::kNoFlags|.
-  static void PrepareDeltas(bool include_persistent,
-                            HistogramBase::Flags flags_to_set,
-                            HistogramBase::Flags required_flags,
-                            HistogramSnapshotManager* snapshot_manager);
-
-  typedef base::Callback<void(HistogramBase::Sample)> OnSampleCallback;
-
-  // Sets the callback to notify when a new sample is recorded on the histogram
-  // referred to by |histogram_name|. Can be called before or after the
-  // histogram is created. Returns whether the callback was successfully set.
-  //
-  // This method is thread safe.
-  static bool SetCallback(const std::string& histogram_name,
-                          const OnSampleCallback& callback);
-
-  // Clears any callback set on the histogram referred to by |histogram_name|.
-  //
-  // This method is thread safe.
-  static void ClearCallback(const std::string& histogram_name);
-
-  // Retrieves the callback for the histogram referred to by |histogram_name|,
-  // or a null callback if no callback exists for this histogram.
-  //
-  // This method is thread safe.
-  static OnSampleCallback FindCallback(const std::string& histogram_name);
-
-  // Returns the number of known histograms.
-  //
-  // This method is thread safe.
-  static size_t GetHistogramCount();
-
-  // Initializes logging histograms with --v=1. Safe to call multiple times.
-  // Is called from ctor but for browser it seems that it is more useful to
-  // start logging after statistics recorder, so we need to init log-on-shutdown
-  // later.
-  //
-  // This method is thread safe.
-  static void InitLogOnShutdown();
-
-  // Removes a histogram from the internal set of known ones. This can be
-  // necessary during testing persistent histograms where the underlying
-  // memory is being released.
-  //
-  // This method is thread safe.
-  static void ForgetHistogramForTesting(base::StringPiece name);
-
-  // Creates a temporary StatisticsRecorder object for testing purposes. All new
-  // histograms will be registered in it until it is destructed or pushed aside
-  // for the lifetime of yet another StatisticsRecorder object. The destruction
-  // of the returned object will re-activate the previous one.
-  // StatisticsRecorder objects must be deleted in the opposite order to which
-  // they're created.
-  //
-  // This method is thread safe.
-  static std::unique_ptr<StatisticsRecorder> CreateTemporaryForTesting()
-      WARN_UNUSED_RESULT;
-
-  // Sets the record checker for determining if a histogram should be recorded.
-  // Record checker doesn't affect any already recorded histograms, so this
-  // method must be called very early, before any threads have started.
-  // Record checker methods can be called on any thread, so they shouldn't
-  // mutate any state.
-  static void SetRecordChecker(
-      std::unique_ptr<RecordHistogramChecker> record_checker);
-
-  // Checks if the given histogram should be recorded based on the
-  // ShouldRecord() method of the record checker. If the record checker is not
-  // set, returns true.
-  //
-  // This method is thread safe.
-  static bool ShouldRecordHistogram(uint64_t histogram_hash);
-
-  // Sorts histograms by name.
-  static Histograms Sort(Histograms histograms);
-
-  // Filters histograms by name. Only histograms which have |query| as a
-  // substring in their name are kept. An empty query keeps all histograms.
-  static Histograms WithName(Histograms histograms, const std::string& query);
-
-  // Filters histograms by persistency. Only non-persistent histograms are kept.
-  static Histograms NonPersistent(Histograms histograms);
-
- private:
-  typedef std::vector<WeakPtr<HistogramProvider>> HistogramProviders;
-
-  typedef std::unordered_map<StringPiece, HistogramBase*, StringPieceHash>
-      HistogramMap;
-
-  // We keep a map of callbacks to histograms, so that as histograms are
-  // created, we can set the callback properly.
-  typedef std::unordered_map<std::string, OnSampleCallback> CallbackMap;
-
-  struct BucketRangesHash {
-    size_t operator()(const BucketRanges* a) const;
-  };
-
-  struct BucketRangesEqual {
-    bool operator()(const BucketRanges* a, const BucketRanges* b) const;
-  };
-
-  typedef std::
-      unordered_set<const BucketRanges*, BucketRangesHash, BucketRangesEqual>
-          RangesMap;
-
-  friend class StatisticsRecorderTest;
-  FRIEND_TEST_ALL_PREFIXES(StatisticsRecorderTest, IterationTest);
-
-  // Initializes the global recorder if it doesn't already exist. Safe to call
-  // multiple times.
-  //
-  // Precondition: The global lock is already acquired.
-  static void EnsureGlobalRecorderWhileLocked();
-
-  // Gets histogram providers.
-  //
-  // This method is thread safe.
-  static HistogramProviders GetHistogramProviders();
-
-  // Imports histograms from global persistent memory.
-  //
-  // Precondition: The global lock must not be held during this call.
-  static void ImportGlobalPersistentHistograms();
-
-  // Constructs a new StatisticsRecorder and sets it as the current global
-  // recorder.
-  //
-  // Precondition: The global lock is already acquired.
-  StatisticsRecorder();
-
-  // Initialize implementation but without lock. Caller should guard
-  // StatisticsRecorder by itself if needed (it isn't in unit tests).
-  //
-  // Precondition: The global lock is already acquired.
-  static void InitLogOnShutdownWhileLocked();
-
-  HistogramMap histograms_;
-  CallbackMap callbacks_;
-  RangesMap ranges_;
-  HistogramProviders providers_;
-  std::unique_ptr<RecordHistogramChecker> record_checker_;
-
-  // Previous global recorder that existed when this one was created.
-  StatisticsRecorder* previous_ = nullptr;
-
-  // Global lock for internal synchronization.
-  static LazyInstance<Lock>::Leaky lock_;
-
-  // Current global recorder. This recorder is used by static methods. When a
-  // new global recorder is created by CreateTemporaryForTesting(), then the
-  // previous global recorder is referenced by top_->previous_.
-  static StatisticsRecorder* top_;
-
-  // Tracks whether InitLogOnShutdownWhileLocked() has registered a logging
-  // function that will be called when the program finishes.
-  static bool is_vlog_initialized_;
-
-  DISALLOW_COPY_AND_ASSIGN(StatisticsRecorder);
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_STATISTICS_RECORDER_H_
diff --git a/base/metrics/user_metrics.cc b/base/metrics/user_metrics.cc
deleted file mode 100644
index 9fcc9e8..0000000
--- a/base/metrics/user_metrics.cc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/metrics/user_metrics.h"
-
-#include <stddef.h>
-
-#include <vector>
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/location.h"
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-
-namespace base {
-namespace {
-
-LazyInstance<std::vector<ActionCallback>>::DestructorAtExit g_callbacks =
-    LAZY_INSTANCE_INITIALIZER;
-LazyInstance<scoped_refptr<SingleThreadTaskRunner>>::DestructorAtExit
-    g_task_runner = LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-void RecordAction(const UserMetricsAction& action) {
-  RecordComputedAction(action.str_);
-}
-
-void RecordComputedAction(const std::string& action) {
-  if (!g_task_runner.Get()) {
-    DCHECK(g_callbacks.Get().empty());
-    return;
-  }
-
-  if (!g_task_runner.Get()->BelongsToCurrentThread()) {
-    g_task_runner.Get()->PostTask(FROM_HERE,
-                                  BindOnce(&RecordComputedAction, action));
-    return;
-  }
-
-  for (const ActionCallback& callback : g_callbacks.Get()) {
-    callback.Run(action);
-  }
-}
-
-void AddActionCallback(const ActionCallback& callback) {
-  // Only allow adding a callback if the task runner is set.
-  DCHECK(g_task_runner.Get());
-  DCHECK(g_task_runner.Get()->BelongsToCurrentThread());
-  g_callbacks.Get().push_back(callback);
-}
-
-void RemoveActionCallback(const ActionCallback& callback) {
-  DCHECK(g_task_runner.Get());
-  DCHECK(g_task_runner.Get()->BelongsToCurrentThread());
-  std::vector<ActionCallback>* callbacks = g_callbacks.Pointer();
-  for (size_t i = 0; i < callbacks->size(); ++i) {
-    if ((*callbacks)[i].Equals(callback)) {
-      callbacks->erase(callbacks->begin() + i);
-      return;
-    }
-  }
-}
-
-void SetRecordActionTaskRunner(
-    scoped_refptr<SingleThreadTaskRunner> task_runner) {
-  DCHECK(task_runner->BelongsToCurrentThread());
-  DCHECK(!g_task_runner.Get() || g_task_runner.Get()->BelongsToCurrentThread());
-  g_task_runner.Get() = task_runner;
-}
-
-}  // namespace base
diff --git a/base/metrics/user_metrics.h b/base/metrics/user_metrics.h
deleted file mode 100644
index 87fbd9c..0000000
--- a/base/metrics/user_metrics.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_USER_METRICS_H_
-#define BASE_METRICS_USER_METRICS_H_
-
-#include <string>
-
-#include "base/base_export.h"
-#include "base/callback.h"
-#include "base/metrics/user_metrics_action.h"
-#include "base/single_thread_task_runner.h"
-
-namespace base {
-
-// This module provides some helper functions for logging actions tracked by
-// the user metrics system.
-
-// For best practices on deciding when to emit a user action, see
-// https://chromium.googlesource.com/chromium/src.git/+/HEAD/tools/metrics/actions/README.md
-
-// Record that the user performed an action.
-// This function must be called after the task runner has been set with
-// SetRecordActionTaskRunner().
-//
-// "Action" here means a user-generated event:
-//   good: "Reload", "CloseTab", and "IMEInvoked"
-//   not good: "SSLDialogShown", "PageLoaded", "DiskFull"
-// We use this to gather anonymized information about how users are
-// interacting with the browser.
-// WARNING: In calls to this function, UserMetricsAction should be followed by a
-// string literal parameter and not a variable e.g.
-//   RecordAction(UserMetricsAction("my action name"));
-// This ensures that our processing scripts can associate this action's hash
-// with its metric name. Therefore, it will be possible to retrieve the metric
-// name from the hash later on.
-//
-// Once a new recorded action is added, run
-//   tools/metrics/actions/extract_actions.py
-// to add the metric to actions.xml, then update the <owner>s and <description>
-// sections. Make sure to include the actions.xml file when you upload your code
-// for review!
-//
-// For more complicated situations (like when there are many different
-// possible actions), see RecordComputedAction().
-BASE_EXPORT void RecordAction(const UserMetricsAction& action);
-
-// This function has identical input and behavior to RecordAction(), but is
-// not automatically found by the action-processing scripts.  It can be used
-// when it's a pain to enumerate all possible actions, but if you use this
-// you need to also update the rules for extracting known actions in
-// tools/metrics/actions/extract_actions.py.
-// This function must be called after the task runner has been set with
-// SetRecordActionTaskRunner().
-BASE_EXPORT void RecordComputedAction(const std::string& action);
-
-// Called with the action string.
-typedef Callback<void(const std::string&)> ActionCallback;
-
-// Add/remove action callbacks (see above).
-// These functions must be called after the task runner has been set with
-// SetRecordActionTaskRunner().
-BASE_EXPORT void AddActionCallback(const ActionCallback& callback);
-BASE_EXPORT void RemoveActionCallback(const ActionCallback& callback);
-
-// Set the task runner on which to record actions.
-BASE_EXPORT void SetRecordActionTaskRunner(
-    scoped_refptr<SingleThreadTaskRunner> task_runner);
-
-}  // namespace base
-
-#endif  // BASE_METRICS_USER_METRICS_H_
diff --git a/base/metrics/user_metrics_action.h b/base/metrics/user_metrics_action.h
deleted file mode 100644
index 454ed83..0000000
--- a/base/metrics/user_metrics_action.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_METRICS_USER_METRICS_ACTION_H_
-#define BASE_METRICS_USER_METRICS_ACTION_H_
-
-namespace base {
-
-// UserMetricsAction exists purely to standardize on the parameters passed to
-// UserMetrics. That way, our toolset can scan the source code reliable for
-// constructors and extract the associated string constants.
-// WARNING: When using UserMetricsAction you should use a string literal
-// parameter e.g.
-//   RecordAction(UserMetricsAction("my action name"));
-// This ensures that our processing scripts can associate this action's hash
-// with its metric name. Therefore, it will be possible to retrieve the metric
-// name from the hash later on.
-// Please see tools/metrics/actions/extract_actions.py for details.
-struct UserMetricsAction {
-  const char* str_;
-  explicit constexpr UserMetricsAction(const char* str) noexcept : str_(str) {}
-};
-
-}  // namespace base
-
-#endif  // BASE_METRICS_USER_METRICS_ACTION_H_
diff --git a/base/process/kill_posix.cc b/base/process/kill_posix.cc
index 5159c19..7d75095 100644
--- a/base/process/kill_posix.cc
+++ b/base/process/kill_posix.cc
@@ -10,7 +10,6 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
-#include "base/debug/activity_tracker.h"
 #include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/macros.h"
diff --git a/base/process/process.h b/base/process/process.h
index 479e24d..2826be3 100644
--- a/base/process/process.h
+++ b/base/process/process.h
@@ -20,16 +20,11 @@
 #endif
 
 #if defined(OS_MACOSX)
-#include "base/feature_list.h"
 #include "base/process/port_provider_mac.h"
 #endif
 
 namespace base {
 
-#if defined(OS_MACOSX)
-extern const Feature kMacAllowBackgroundingProcesses;
-#endif
-
 // Provides a move-only encapsulation of a process.
 //
 // This object is not tied to the lifetime of the underlying process: the
diff --git a/base/process/process_mac.cc b/base/process/process_mac.cc
index 70bc4c2..cd47c62 100644
--- a/base/process/process_mac.cc
+++ b/base/process/process_mac.cc
@@ -6,17 +6,12 @@
 
 #include <mach/mach.h>
 
-#include "base/feature_list.h"
 #include "base/mac/mach_logging.h"
 
 namespace base {
 
-// Enables backgrounding hidden renderers on Mac.
-const Feature kMacAllowBackgroundingProcesses{"MacAllowBackgroundingProcesses",
-                                              FEATURE_DISABLED_BY_DEFAULT};
-
 bool Process::CanBackgroundProcesses() {
-  return FeatureList::IsEnabled(kMacAllowBackgroundingProcesses);
+  return false;
 }
 
 bool Process::IsProcessBackgrounded(PortProvider* port_provider) const {
diff --git a/base/process/process_posix.cc b/base/process/process_posix.cc
index 51b57e1..6b758a2 100644
--- a/base/process/process_posix.cc
+++ b/base/process/process_posix.cc
@@ -10,7 +10,6 @@
 #include <sys/resource.h>
 #include <sys/wait.h>
 
-#include "base/debug/activity_tracker.h"
 #include "base/files/scoped_file.h"
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
@@ -339,9 +338,6 @@
   if (!timeout.is_zero())
     internal::AssertBaseSyncPrimitivesAllowed();
 
-  // Record the event that this thread is blocking upon (for hang diagnosis).
-  base::debug::ScopedProcessWaitActivity process_activity(this);
-
   int local_exit_code;
   bool exited = WaitForExitWithTimeoutImpl(Handle(), &local_exit_code, timeout);
   if (exited) {
diff --git a/base/synchronization/lock_impl_posix.cc b/base/synchronization/lock_impl_posix.cc
index 1cfa88a..3812fe2 100644
--- a/base/synchronization/lock_impl_posix.cc
+++ b/base/synchronization/lock_impl_posix.cc
@@ -6,7 +6,6 @@
 
 #include <string>
 
-#include "base/debug/activity_tracker.h"
 #include "base/logging.h"
 #include "base/posix/safe_strerror.h"
 #include "base/strings/stringprintf.h"
@@ -86,18 +85,6 @@
 }
 
 void LockImpl::Lock() {
-  // The ScopedLockAcquireActivity below is relatively expensive and so its
-  // actions can become significant due to the very large number of locks
-  // that tend to be used throughout the build. To avoid this cost in the
-  // vast majority of the calls, simply "try" the lock first and only do the
-  // (tracked) blocking call if that fails. Since "try" itself is a system
-  // call, and thus also somewhat expensive, don't bother with it unless
-  // tracking is actually enabled.
-  if (base::debug::GlobalActivityTracker::IsEnabled())
-    if (Try())
-      return;
-
-  base::debug::ScopedLockAcquireActivity lock_activity(this);
   int rv = pthread_mutex_lock(&native_handle_);
   DCHECK_EQ(rv, 0) << ". " << SystemErrorCodeToString(rv);
 }
diff --git a/base/synchronization/waitable_event_mac.cc b/base/synchronization/waitable_event_mac.cc
index 56e6cb3..7979553 100644
--- a/base/synchronization/waitable_event_mac.cc
+++ b/base/synchronization/waitable_event_mac.cc
@@ -8,7 +8,7 @@
 #include <mach/mach.h>
 #include <sys/event.h>
 
-#include "base/debug/activity_tracker.h"
+#include "base/callback.h"
 #include "base/files/scoped_file.h"
 #include "base/mac/dispatch_source_mach.h"
 #include "base/mac/mac_util.h"
@@ -113,8 +113,6 @@
 bool WaitableEvent::TimedWaitUntil(const TimeTicks& end_time) {
   internal::AssertBaseSyncPrimitivesAllowed();
   ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK);
-  // Record the event that this thread is blocking upon (for hang diagnosis).
-  debug::ScopedEventWaitActivity event_activity(this);
 
   TimeDelta wait_time = end_time - TimeTicks::Now();
   if (wait_time < TimeDelta()) {
@@ -169,8 +167,6 @@
   internal::AssertBaseSyncPrimitivesAllowed();
   DCHECK(count) << "Cannot wait on no events";
   ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK);
-  // Record an event (the first) that this thread is blocking upon.
-  debug::ScopedEventWaitActivity event_activity(raw_waitables[0]);
 
   // On macOS 10.11+, using Mach port sets may cause system instability, per
   // https://crbug.com/756102. On macOS 10.12+, a kqueue can be used
diff --git a/base/synchronization/waitable_event_posix.cc b/base/synchronization/waitable_event_posix.cc
index 9799e7d..34d54c7 100644
--- a/base/synchronization/waitable_event_posix.cc
+++ b/base/synchronization/waitable_event_posix.cc
@@ -8,7 +8,6 @@
 #include <limits>
 #include <vector>
 
-#include "base/debug/activity_tracker.h"
 #include "base/logging.h"
 #include "base/synchronization/condition_variable.h"
 #include "base/synchronization/lock.h"
@@ -164,8 +163,6 @@
 bool WaitableEvent::TimedWaitUntil(const TimeTicks& end_time) {
   internal::AssertBaseSyncPrimitivesAllowed();
   ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK);
-  // Record the event that this thread is blocking upon (for hang diagnosis).
-  base::debug::ScopedEventWaitActivity event_activity(this);
 
   const bool finite_time = !end_time.is_max();
 
@@ -240,8 +237,6 @@
   internal::AssertBaseSyncPrimitivesAllowed();
   DCHECK(count) << "Cannot wait on no events";
   ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK);
-  // Record an event (the first) that this thread is blocking upon.
-  base::debug::ScopedEventWaitActivity event_activity(raw_waitables[0]);
 
   // We need to acquire the locks in a globally consistent order. Thus we sort
   // the array of waitables by address. We actually sort a pairs so that we can
diff --git a/base/task_scheduler/scheduler_worker_pool_impl.cc b/base/task_scheduler/scheduler_worker_pool_impl.cc
index 0e0c107..9e7e892 100644
--- a/base/task_scheduler/scheduler_worker_pool_impl.cc
+++ b/base/task_scheduler/scheduler_worker_pool_impl.cc
@@ -16,7 +16,6 @@
 #include "base/compiler_specific.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
-#include "base/metrics/histogram.h"
 #include "base/sequence_token.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -41,13 +40,6 @@
 
 namespace {
 
-constexpr char kPoolNameSuffix[] = "Pool";
-constexpr char kDetachDurationHistogramPrefix[] =
-    "TaskScheduler.DetachDuration.";
-constexpr char kNumTasksBeforeDetachHistogramPrefix[] =
-    "TaskScheduler.NumTasksBeforeDetach.";
-constexpr char kNumTasksBetweenWaitsHistogramPrefix[] =
-    "TaskScheduler.NumTasksBetweenWaits.";
 constexpr size_t kMaxNumberOfWorkers = 256;
 
 // Only used in DCHECKs.
@@ -168,38 +160,6 @@
       priority_hint_(priority_hint),
       lock_(shared_priority_queue_.container_lock()),
       idle_workers_stack_cv_for_testing_(lock_.CreateConditionVariable()),
-      // Mimics the UMA_HISTOGRAM_LONG_TIMES macro.
-      detach_duration_histogram_(Histogram::FactoryTimeGet(
-          JoinString({kDetachDurationHistogramPrefix, histogram_label,
-                      kPoolNameSuffix},
-                     ""),
-          TimeDelta::FromMilliseconds(1),
-          TimeDelta::FromHours(1),
-          50,
-          HistogramBase::kUmaTargetedHistogramFlag)),
-      // Mimics the UMA_HISTOGRAM_COUNTS_1000 macro. When a worker runs more
-      // than 1000 tasks before detaching, there is no need to know the exact
-      // number of tasks that ran.
-      num_tasks_before_detach_histogram_(Histogram::FactoryGet(
-          JoinString({kNumTasksBeforeDetachHistogramPrefix, histogram_label,
-                      kPoolNameSuffix},
-                     ""),
-          1,
-          1000,
-          50,
-          HistogramBase::kUmaTargetedHistogramFlag)),
-      // Mimics the UMA_HISTOGRAM_COUNTS_100 macro. A SchedulerWorker is
-      // expected to run between zero and a few tens of tasks between waits.
-      // When it runs more than 100 tasks, there is no need to know the exact
-      // number of tasks that ran.
-      num_tasks_between_waits_histogram_(Histogram::FactoryGet(
-          JoinString({kNumTasksBetweenWaitsHistogramPrefix, histogram_label,
-                      kPoolNameSuffix},
-                     ""),
-          1,
-          100,
-          50,
-          HistogramBase::kUmaTargetedHistogramFlag)),
       tracked_ref_factory_(this) {
   DCHECK(!histogram_label.empty());
   DCHECK(!pool_label_.empty());
@@ -271,12 +231,6 @@
   WakeUpOneWorker();
 }
 
-void SchedulerWorkerPoolImpl::GetHistograms(
-    std::vector<const HistogramBase*>* histograms) const {
-  histograms->push_back(detach_duration_histogram_);
-  histograms->push_back(num_tasks_between_waits_histogram_);
-}
-
 int SchedulerWorkerPoolImpl::GetMaxConcurrentNonBlockedTasksDeprecated() const {
 #if DCHECK_IS_ON()
   AutoSchedulerLock auto_lock(lock_);
@@ -521,7 +475,6 @@
   DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
 
   outer_->lock_.AssertAcquired();
-  outer_->num_tasks_before_detach_histogram_->Add(num_tasks_since_last_detach_);
   outer_->cleanup_timestamps_.push(TimeTicks::Now());
   worker->Cleanup();
   outer_->RemoveFromIdleWorkersStackLockRequired(worker);
@@ -546,7 +499,6 @@
   // returns nullptr, the SchedulerWorker will perform a wait on its
   // WaitableEvent, so we record how many tasks were ran since the last wait
   // here.
-  outer_->num_tasks_between_waits_histogram_->Add(num_tasks_since_last_wait_);
   num_tasks_since_last_wait_ = 0;
   outer_->AddToIdleWorkersStackLockRequired(worker);
   SetIsOnIdleWorkersStackLockRequired(worker);
@@ -843,8 +795,6 @@
   DCHECK_LE(workers_.size(), worker_capacity_);
 
   if (!cleanup_timestamps_.empty()) {
-    detach_duration_histogram_->AddTime(TimeTicks::Now() -
-                                        cleanup_timestamps_.top());
     cleanup_timestamps_.pop();
   }
   return worker.get();
diff --git a/base/task_scheduler/scheduler_worker_pool_impl.h b/base/task_scheduler/scheduler_worker_pool_impl.h
index 997fcc9..d331d3c 100644
--- a/base/task_scheduler/scheduler_worker_pool_impl.h
+++ b/base/task_scheduler/scheduler_worker_pool_impl.h
@@ -34,7 +34,6 @@
 
 namespace base {
 
-class HistogramBase;
 class SchedulerWorkerObserver;
 class SchedulerWorkerPoolParams;
 
@@ -95,16 +94,6 @@
   // SchedulerWorkerPool:
   void JoinForTesting() override;
 
-  const HistogramBase* num_tasks_before_detach_histogram() const {
-    return num_tasks_before_detach_histogram_;
-  }
-
-  const HistogramBase* num_tasks_between_waits_histogram() const {
-    return num_tasks_between_waits_histogram_;
-  }
-
-  void GetHistograms(std::vector<const HistogramBase*>* histograms) const;
-
   // Returns the maximum number of non-blocked tasks that can run concurrently
   // in this pool.
   //
@@ -306,18 +295,6 @@
   AtomicFlag join_for_testing_started_;
 #endif
 
-  // TaskScheduler.DetachDuration.[worker pool name] histogram. Intentionally
-  // leaked.
-  HistogramBase* const detach_duration_histogram_;
-
-  // TaskScheduler.NumTasksBeforeDetach.[worker pool name] histogram.
-  // Intentionally leaked.
-  HistogramBase* const num_tasks_before_detach_histogram_;
-
-  // TaskScheduler.NumTasksBetweenWaits.[worker pool name] histogram.
-  // Intentionally leaked.
-  HistogramBase* const num_tasks_between_waits_histogram_;
-
   scoped_refptr<TaskRunner> service_thread_task_runner_;
 
   // Optional observer notified when a worker enters and exits its main
diff --git a/base/task_scheduler/service_thread.cc b/base/task_scheduler/service_thread.cc
index 40f217f..ce8bf4d 100644
--- a/base/task_scheduler/service_thread.cc
+++ b/base/task_scheduler/service_thread.cc
@@ -13,17 +13,9 @@
 namespace base {
 namespace internal {
 
-ServiceThread::ServiceThread(const TaskTracker* task_tracker)
-    : Thread("TaskSchedulerServiceThread"), task_tracker_(task_tracker) {}
+ServiceThread::ServiceThread() : Thread("TaskSchedulerServiceThread") {}
 
-void ServiceThread::Init() {
-  if (task_tracker_) {
-    heartbeat_latency_timer_.Start(
-        FROM_HERE, TimeDelta::FromSeconds(5),
-        BindRepeating(&ServiceThread::PerformHeartbeatLatencyReport,
-                      Unretained(this)));
-  }
-}
+void ServiceThread::Init() {}
 
 NOINLINE void ServiceThread::Run(RunLoop* run_loop) {
   const int line_number = __LINE__;
@@ -31,23 +23,5 @@
   base::debug::Alias(&line_number);
 }
 
-void ServiceThread::PerformHeartbeatLatencyReport() const {
-  static constexpr TaskTraits kReportedTraits[] = {
-      {TaskPriority::BACKGROUND},    {TaskPriority::BACKGROUND, MayBlock()},
-      {TaskPriority::USER_VISIBLE},  {TaskPriority::USER_VISIBLE, MayBlock()},
-      {TaskPriority::USER_BLOCKING}, {TaskPriority::USER_BLOCKING, MayBlock()}};
-
-  for (auto& traits : kReportedTraits) {
-    // Post through the static API to time the full stack. Use a new Now() for
-    // every set of traits in case PostTaskWithTraits() itself is slow.
-    base::PostTaskWithTraits(
-        FROM_HERE, traits,
-        BindOnce(&TaskTracker::RecordLatencyHistogram,
-                 Unretained(task_tracker_),
-                 TaskTracker::LatencyHistogramType::HEARTBEAT_LATENCY, traits,
-                 TimeTicks::Now()));
-  }
-}
-
 }  // namespace internal
 }  // namespace base
diff --git a/base/task_scheduler/service_thread.h b/base/task_scheduler/service_thread.h
index f9b23fa..14ccd76 100644
--- a/base/task_scheduler/service_thread.h
+++ b/base/task_scheduler/service_thread.h
@@ -27,24 +27,13 @@
   // |task_tracker| if non-null. In that case, this ServiceThread will assume a
   // registered TaskScheduler instance and that |task_tracker| will outlive this
   // ServiceThread.
-  explicit ServiceThread(const TaskTracker* task_tracker);
+  ServiceThread();
 
  private:
   // Thread:
   void Init() override;
   void Run(RunLoop* run_loop) override;
 
-  // Kicks off async tasks which will record a histogram on the latency of
-  // various traits.
-  void PerformHeartbeatLatencyReport() const;
-
-  const TaskTracker* const task_tracker_;
-
-  // Fires a recurring heartbeat task to record latency histograms which are
-  // independent from any execution sequence. This is done on the service thread
-  // to avoid all external dependencies (even main thread).
-  base::RepeatingTimer heartbeat_latency_timer_;
-
   DISALLOW_COPY_AND_ASSIGN(ServiceThread);
 };
 
diff --git a/base/task_scheduler/task_scheduler.h b/base/task_scheduler/task_scheduler.h
index 8881028..3135f8c 100644
--- a/base/task_scheduler/task_scheduler.h
+++ b/base/task_scheduler/task_scheduler.h
@@ -136,9 +136,6 @@
       SingleThreadTaskRunnerThreadMode thread_mode) = 0;
 #endif  // defined(OS_WIN)
 
-  // Returns a vector of all histograms available in this task scheduler.
-  virtual std::vector<const HistogramBase*> GetHistograms() const = 0;
-
   // Synchronously shuts down the scheduler. Once this is called, only tasks
   // posted with the BLOCK_SHUTDOWN behavior will be run. When this returns:
   // - All SKIP_ON_SHUTDOWN tasks that were already running have completed their
diff --git a/base/task_scheduler/task_scheduler_impl.cc b/base/task_scheduler/task_scheduler_impl.cc
index a5ab06c..88250c2 100644
--- a/base/task_scheduler/task_scheduler_impl.cc
+++ b/base/task_scheduler/task_scheduler_impl.cc
@@ -9,7 +9,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/message_loop/message_loop.h"
-#include "base/metrics/field_trial_params.h"
 #include "base/strings/string_util.h"
 #include "base/task_scheduler/delayed_task_manager.h"
 #include "base/task_scheduler/environment_config.h"
@@ -32,7 +31,7 @@
     StringPiece histogram_label,
     std::unique_ptr<TaskTrackerImpl> task_tracker)
     : task_tracker_(std::move(task_tracker)),
-      service_thread_(std::make_unique<ServiceThread>(task_tracker_.get())),
+      service_thread_(std::make_unique<ServiceThread>()),
       single_thread_task_runner_manager_(task_tracker_->GetTrackedRef(),
                                          &delayed_task_manager_) {
   DCHECK(!histogram_label.empty());
@@ -64,13 +63,6 @@
 void TaskSchedulerImpl::Start(
     const TaskScheduler::InitParams& init_params,
     SchedulerWorkerObserver* scheduler_worker_observer) {
-  // This is set in Start() and not in the constructor because variation params
-  // are usually not ready when TaskSchedulerImpl is instantiated in a process.
-  if (base::GetFieldTrialParamValue("BrowserScheduler",
-                                    "AllTasksUserBlocking") == "true") {
-    all_tasks_user_blocking_.Set();
-  }
-
   // Start the service thread. On platforms that support it (POSIX except NaCL
   // SFI), the service thread runs a MessageLoopForIO which is used to support
   // FileDescriptorWatcher in the scope in which tasks run.
@@ -174,14 +166,6 @@
 }
 #endif  // defined(OS_WIN)
 
-std::vector<const HistogramBase*> TaskSchedulerImpl::GetHistograms() const {
-  std::vector<const HistogramBase*> histograms;
-  for (const auto& worker_pool : worker_pools_)
-    worker_pool->GetHistograms(&histograms);
-
-  return histograms;
-}
-
 int TaskSchedulerImpl::GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
     const TaskTraits& traits) const {
   return GetWorkerPoolForTraits(traits)
@@ -225,9 +209,7 @@
 
 TaskTraits TaskSchedulerImpl::SetUserBlockingPriorityIfNeeded(
     const TaskTraits& traits) const {
-  return all_tasks_user_blocking_.IsSet()
-             ? TaskTraits::Override(traits, {TaskPriority::USER_BLOCKING})
-             : traits;
+  return traits;
 }
 
 }  // namespace internal
diff --git a/base/task_scheduler/task_scheduler_impl.h b/base/task_scheduler/task_scheduler_impl.h
index 4ad7fc2..f409dc5 100644
--- a/base/task_scheduler/task_scheduler_impl.h
+++ b/base/task_scheduler/task_scheduler_impl.h
@@ -79,7 +79,6 @@
       const TaskTraits& traits,
       SingleThreadTaskRunnerThreadMode thread_mode) override;
 #endif  // defined(OS_WIN)
-  std::vector<const HistogramBase*> GetHistograms() const override;
   int GetMaxConcurrentNonBlockedTasksWithTraitsDeprecated(
       const TaskTraits& traits) const override;
   void Shutdown() override;
@@ -101,14 +100,6 @@
   DelayedTaskManager delayed_task_manager_;
   SchedulerSingleThreadTaskRunnerManager single_thread_task_runner_manager_;
 
-  // Indicates that all tasks are handled as if they had been posted with
-  // TaskPriority::USER_BLOCKING. Since this is set in Start(), it doesn't apply
-  // to tasks posted before Start() or to tasks posted to TaskRunners created
-  // before Start().
-  //
-  // TODO(fdoray): Remove after experiment. https://crbug.com/757022
-  AtomicFlag all_tasks_user_blocking_;
-
   // There are 4 SchedulerWorkerPoolImpl in this array to match the 4
   // SchedulerWorkerPoolParams in TaskScheduler::InitParams.
   std::unique_ptr<SchedulerWorkerPoolImpl> worker_pools_[4];
diff --git a/base/task_scheduler/task_tracker.cc b/base/task_scheduler/task_tracker.cc
index 4fd2356..33424bb 100644
--- a/base/task_scheduler/task_tracker.cc
+++ b/base/task_scheduler/task_tracker.cc
@@ -13,7 +13,6 @@
 #include "base/command_line.h"
 #include "base/json/json_writer.h"
 #include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
 #include "base/sequence_token.h"
 #include "base/strings/string_util.h"
 #include "base/synchronization/condition_variable.h"
@@ -52,45 +51,6 @@
   DISALLOW_COPY_AND_ASSIGN(TaskTracingInfo);
 };
 
-// These name conveys that a Task is posted to/run by the task scheduler without
-// revealing its implementation details.
-constexpr char kQueueFunctionName[] = "TaskScheduler PostTask";
-constexpr char kRunFunctionName[] = "TaskScheduler RunTask";
-
-// Constructs a histogram to track latency which is logging to
-// "TaskScheduler.{histogram_name}.{histogram_label}.{task_type_suffix}".
-HistogramBase* GetLatencyHistogram(StringPiece histogram_name,
-                                   StringPiece histogram_label,
-                                   StringPiece task_type_suffix) {
-  DCHECK(!histogram_name.empty());
-  DCHECK(!histogram_label.empty());
-  DCHECK(!task_type_suffix.empty());
-  // Mimics the UMA_HISTOGRAM_HIGH_RESOLUTION_CUSTOM_TIMES macro. The minimums
-  // and maximums were chosen to place the 1ms mark at around the 70% range
-  // coverage for buckets giving us good info for tasks that have a latency
-  // below 1ms (most of them) and enough info to assess how bad the latency is
-  // for tasks that exceed this threshold.
-  const std::string histogram = JoinString(
-      {"TaskScheduler", histogram_name, histogram_label, task_type_suffix},
-      ".");
-  return Histogram::FactoryMicrosecondsTimeGet(
-      histogram, TimeDelta::FromMicroseconds(1),
-      TimeDelta::FromMilliseconds(20), 50,
-      HistogramBase::kUmaTargetedHistogramFlag);
-}
-
-// Upper bound for the
-// TaskScheduler.BlockShutdownTasksPostedDuringShutdown histogram.
-constexpr HistogramBase::Sample kMaxBlockShutdownTasksPostedDuringShutdown =
-    1000;
-
-void RecordNumBlockShutdownTasksPostedDuringShutdown(
-    HistogramBase::Sample value) {
-  UMA_HISTOGRAM_CUSTOM_COUNTS(
-      "TaskScheduler.BlockShutdownTasksPostedDuringShutdown", value, 1,
-      kMaxBlockShutdownTasksPostedDuringShutdown, 50);
-}
-
 // Returns the maximum number of TaskPriority::BACKGROUND sequences that can be
 // scheduled concurrently based on command line flags.
 int GetMaxNumScheduledBackgroundSequences() {
@@ -235,49 +195,7 @@
       shutdown_lock_(&flush_lock_),
       max_num_scheduled_background_sequences_(
           max_num_scheduled_background_sequences),
-      task_latency_histograms_{
-          {GetLatencyHistogram("TaskLatencyMicroseconds",
-                               histogram_label,
-                               "BackgroundTaskPriority"),
-           GetLatencyHistogram("TaskLatencyMicroseconds",
-                               histogram_label,
-                               "BackgroundTaskPriority_MayBlock")},
-          {GetLatencyHistogram("TaskLatencyMicroseconds",
-                               histogram_label,
-                               "UserVisibleTaskPriority"),
-           GetLatencyHistogram("TaskLatencyMicroseconds",
-                               histogram_label,
-                               "UserVisibleTaskPriority_MayBlock")},
-          {GetLatencyHistogram("TaskLatencyMicroseconds",
-                               histogram_label,
-                               "UserBlockingTaskPriority"),
-           GetLatencyHistogram("TaskLatencyMicroseconds",
-                               histogram_label,
-                               "UserBlockingTaskPriority_MayBlock")}},
-      heartbeat_latency_histograms_{
-          {GetLatencyHistogram("HeartbeatLatencyMicroseconds",
-                               histogram_label,
-                               "BackgroundTaskPriority"),
-           GetLatencyHistogram("HeartbeatLatencyMicroseconds",
-                               histogram_label,
-                               "BackgroundTaskPriority_MayBlock")},
-          {GetLatencyHistogram("HeartbeatLatencyMicroseconds",
-                               histogram_label,
-                               "UserVisibleTaskPriority"),
-           GetLatencyHistogram("HeartbeatLatencyMicroseconds",
-                               histogram_label,
-                               "UserVisibleTaskPriority_MayBlock")},
-          {GetLatencyHistogram("HeartbeatLatencyMicroseconds",
-                               histogram_label,
-                               "UserBlockingTaskPriority"),
-           GetLatencyHistogram("HeartbeatLatencyMicroseconds",
-                               histogram_label,
-                               "UserBlockingTaskPriority_MayBlock")}},
       tracked_ref_factory_(this) {
-  // Confirm that all |task_latency_histograms_| have been initialized above.
-  DCHECK(*(&task_latency_histograms_[static_cast<int>(TaskPriority::HIGHEST) +
-                                     1][0] -
-           1));
 }
 
 TaskTracker::~TaskTracker() = default;
@@ -419,22 +337,9 @@
   state_->StartShutdown();
 }
 
-void TaskTracker::RecordLatencyHistogram(
-    LatencyHistogramType latency_histogram_type,
-    TaskTraits task_traits,
-    TimeTicks posted_time) const {
-  const TimeDelta task_latency = TimeTicks::Now() - posted_time;
-
-  DCHECK(latency_histogram_type == LatencyHistogramType::TASK_LATENCY ||
-         latency_histogram_type == LatencyHistogramType::HEARTBEAT_LATENCY);
-}
-
 void TaskTracker::RunOrSkipTask(Task task,
                                 Sequence* sequence,
                                 bool can_run_task) {
-  RecordLatencyHistogram(LatencyHistogramType::TASK_LATENCY, task.traits,
-                         task.sequenced_time);
-
   const bool previous_singleton_allowed =
       ThreadRestrictions::SetSingletonAllowed(
           task.traits.shutdown_behavior() !=
@@ -488,7 +393,6 @@
 
     // This method can only be called once.
     DCHECK(!shutdown_event_);
-    DCHECK(!num_block_shutdown_tasks_posted_during_shutdown_);
     DCHECK(!state_->HasShutdownStarted());
 
     shutdown_event_.reset(
@@ -523,20 +427,6 @@
     base::ThreadRestrictions::ScopedAllowWait allow_wait;
     shutdown_event_->Wait();
   }
-
-  {
-    AutoSchedulerLock auto_lock(shutdown_lock_);
-
-    // Record TaskScheduler.BlockShutdownTasksPostedDuringShutdown if less than
-    // |kMaxBlockShutdownTasksPostedDuringShutdown| BLOCK_SHUTDOWN tasks were
-    // posted during shutdown. Otherwise, the histogram has already been
-    // recorded in BeforePostTask().
-    if (num_block_shutdown_tasks_posted_during_shutdown_ <
-        kMaxBlockShutdownTasksPostedDuringShutdown) {
-      RecordNumBlockShutdownTasksPostedDuringShutdown(
-          num_block_shutdown_tasks_posted_during_shutdown_);
-    }
-  }
 }
 
 void TaskTracker::SetMaxNumScheduledBackgroundSequences(
@@ -626,18 +516,6 @@
         state_->DecrementNumTasksBlockingShutdown();
         return false;
       }
-
-      ++num_block_shutdown_tasks_posted_during_shutdown_;
-
-      if (num_block_shutdown_tasks_posted_during_shutdown_ ==
-          kMaxBlockShutdownTasksPostedDuringShutdown) {
-        // Record the TaskScheduler.BlockShutdownTasksPostedDuringShutdown
-        // histogram as soon as its upper bound is hit. That way, a value will
-        // be recorded even if an infinite number of BLOCK_SHUTDOWN tasks are
-        // posted, preventing shutdown to complete.
-        RecordNumBlockShutdownTasksPostedDuringShutdown(
-            num_block_shutdown_tasks_posted_during_shutdown_);
-      }
     }
 
     return true;
diff --git a/base/task_scheduler/task_tracker.h b/base/task_scheduler/task_tracker.h
index 760a8f7..ae484ce 100644
--- a/base/task_scheduler/task_tracker.h
+++ b/base/task_scheduler/task_tracker.h
@@ -15,7 +15,6 @@
 #include "base/debug/task_annotator.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/metrics/histogram_base.h"
 #include "base/strings/string_piece.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/task_scheduler/can_schedule_sequence_observer.h"
@@ -28,7 +27,6 @@
 namespace base {
 
 class ConditionVariable;
-class HistogramBase;
 
 namespace internal {
 
@@ -160,27 +158,11 @@
   // Returns true if shutdown has completed (Shutdown() has returned).
   bool IsShutdownComplete() const;
 
-  enum class LatencyHistogramType {
-    // Records the latency of each individual task posted through TaskTracker.
-    TASK_LATENCY,
-    // Records the latency of heartbeat tasks which are independent of current
-    // workload. These avoid a bias towards TASK_LATENCY reporting that high-
-    // priority tasks are "slower" than regular tasks because high-priority
-    // tasks tend to be correlated with heavy workloads.
-    HEARTBEAT_LATENCY,
-  };
-
   // Causes HasShutdownStarted() to return true. Unlike when Shutdown() returns,
   // IsShutdownComplete() won't return true after this returns. Shutdown()
   // cannot be called after this.
   void SetHasShutdownStartedForTesting();
 
-  // Records |Now() - posted_time| to the appropriate |latency_histogram_type|
-  // based on |task_traits|.
-  void RecordLatencyHistogram(LatencyHistogramType latency_histogram_type,
-                              TaskTraits task_traits,
-                              TimeTicks posted_time) const;
-
   TrackedRef<TaskTracker> GetTrackedRef() {
     return tracked_ref_factory_.GetTrackedRef();
   }
@@ -331,20 +313,6 @@
   // Number of currently scheduled background sequences.
   int num_scheduled_background_sequences_ = 0;
 
-  // TaskScheduler.TaskLatencyMicroseconds.* and
-  // TaskScheduler.HeartbeatLatencyMicroseconds.* histograms. The first index is
-  // a TaskPriority. The second index is 0 for non-blocking tasks, 1 for
-  // blocking tasks. Intentionally leaked.
-  // TODO(scheduler-dev): Consider using STATIC_HISTOGRAM_POINTER_GROUP for
-  // these.
-  static constexpr int kNumTaskPriorities =
-      static_cast<int>(TaskPriority::HIGHEST) + 1;
-  HistogramBase* const task_latency_histograms_[kNumTaskPriorities][2];
-  HistogramBase* const heartbeat_latency_histograms_[kNumTaskPriorities][2];
-
-  // Number of BLOCK_SHUTDOWN tasks posted during shutdown.
-  HistogramBase::Sample num_block_shutdown_tasks_posted_during_shutdown_ = 0;
-
   // Ensures all state (e.g. dangling cleaned up workers) is coalesced before
   // destroying the TaskTracker (e.g. in test environments).
   // Ref. https://crbug.com/827615.
diff --git a/base/test/histogram_tester.cc b/base/test/histogram_tester.cc
deleted file mode 100644
index 2a63b8c..0000000
--- a/base/test/histogram_tester.cc
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/test/histogram_tester.h"
-
-#include <stddef.h>
-
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/metrics_hashes.h"
-#include "base/metrics/sample_map.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/strings/string_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace base {
-
-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();
-  }
-}
-
-HistogramTester::~HistogramTester() = default;
-
-void HistogramTester::ExpectUniqueSample(
-    const std::string& name,
-    HistogramBase::Sample sample,
-    HistogramBase::Count expected_count) const {
-  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
-  EXPECT_NE(nullptr, histogram) << "Histogram \"" << name
-                                << "\" does not exist.";
-
-  if (histogram) {
-    std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
-    CheckBucketCount(name, sample, expected_count, *samples);
-    CheckTotalCount(name, expected_count, *samples);
-  }
-}
-
-void HistogramTester::ExpectBucketCount(
-    const std::string& name,
-    HistogramBase::Sample sample,
-    HistogramBase::Count expected_count) const {
-  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
-  EXPECT_NE(nullptr, histogram) << "Histogram \"" << name
-                                << "\" does not exist.";
-
-  if (histogram) {
-    std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
-    CheckBucketCount(name, sample, expected_count, *samples);
-  }
-}
-
-void HistogramTester::ExpectTotalCount(const std::string& name,
-                                       HistogramBase::Count count) const {
-  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
-  if (histogram) {
-    std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
-    CheckTotalCount(name, count, *samples);
-  } else {
-    // No histogram means there were zero samples.
-    EXPECT_EQ(count, 0) << "Histogram \"" << name << "\" does not exist.";
-  }
-}
-
-void HistogramTester::ExpectTimeBucketCount(const std::string& name,
-                                            TimeDelta sample,
-                                            HistogramBase::Count count) const {
-  ExpectBucketCount(name, sample.InMilliseconds(), count);
-}
-
-std::vector<Bucket> HistogramTester::GetAllSamples(
-    const std::string& name) const {
-  std::vector<Bucket> samples;
-  std::unique_ptr<HistogramSamples> snapshot =
-      GetHistogramSamplesSinceCreation(name);
-  if (snapshot) {
-    for (auto it = snapshot->Iterator(); !it->Done(); it->Next()) {
-      HistogramBase::Sample sample;
-      HistogramBase::Count count;
-      it->Get(&sample, nullptr, &count);
-      samples.push_back(Bucket(sample, count));
-    }
-  }
-  return samples;
-}
-
-HistogramBase::Count HistogramTester::GetBucketCount(
-    const std::string& name,
-    HistogramBase::Sample sample) const {
-  HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
-  EXPECT_NE(nullptr, histogram)
-      << "Histogram \"" << name << "\" does not exist.";
-  HistogramBase::Count count = 0;
-  if (histogram) {
-    std::unique_ptr<HistogramSamples> samples = histogram->SnapshotSamples();
-    GetBucketCountForSamples(name, sample, *samples, &count);
-  }
-  return count;
-}
-
-void HistogramTester::GetBucketCountForSamples(
-    const std::string& name,
-    HistogramBase::Sample sample,
-    const HistogramSamples& samples,
-    HistogramBase::Count* count) const {
-  *count = samples.GetCount(sample);
-  auto histogram_data = histograms_snapshot_.find(name);
-  if (histogram_data != histograms_snapshot_.end())
-    *count -= histogram_data->second->GetCount(sample);
-}
-
-HistogramTester::CountsMap HistogramTester::GetTotalCountsForPrefix(
-    const std::string& prefix) const {
-  EXPECT_TRUE(prefix.find('.') != std::string::npos)
-      << "|prefix| ought to contain at least one period, to avoid matching too"
-      << " many histograms.";
-
-  CountsMap result;
-
-  // Find candidate matches by using the logic built into GetSnapshot().
-  for (const HistogramBase* histogram : StatisticsRecorder::GetHistograms()) {
-    if (!StartsWith(histogram->histogram_name(), prefix,
-                    CompareCase::SENSITIVE)) {
-      continue;
-    }
-    std::unique_ptr<HistogramSamples> new_samples =
-        GetHistogramSamplesSinceCreation(histogram->histogram_name());
-    // Omit unchanged histograms from the result.
-    if (new_samples->TotalCount()) {
-      result[histogram->histogram_name()] = new_samples->TotalCount();
-    }
-  }
-  return result;
-}
-
-std::unique_ptr<HistogramSamples>
-HistogramTester::GetHistogramSamplesSinceCreation(
-    const std::string& histogram_name) const {
-  HistogramBase* histogram = StatisticsRecorder::FindHistogram(histogram_name);
-  // Whether the histogram exists or not may not depend on the current test
-  // calling this method, but rather on which tests ran before and possibly
-  // generated a histogram or not (see http://crbug.com/473689). To provide a
-  // response which is independent of the previously run tests, this method
-  // creates empty samples in the absence of the histogram, rather than
-  // returning null.
-  if (!histogram) {
-    return std::unique_ptr<HistogramSamples>(
-        new SampleMap(HashMetricName(histogram_name)));
-  }
-  std::unique_ptr<HistogramSamples> named_samples =
-      histogram->SnapshotSamples();
-  auto original_samples_it = histograms_snapshot_.find(histogram_name);
-  if (original_samples_it != histograms_snapshot_.end())
-    named_samples->Subtract(*original_samples_it->second.get());
-  return named_samples;
-}
-
-void HistogramTester::CheckBucketCount(const std::string& name,
-                                       HistogramBase::Sample sample,
-                                       HistogramBase::Count expected_count,
-                                       const HistogramSamples& samples) const {
-  int actual_count;
-  GetBucketCountForSamples(name, sample, samples, &actual_count);
-
-  EXPECT_EQ(expected_count, actual_count)
-      << "Histogram \"" << name
-      << "\" does not have the right number of samples (" << expected_count
-      << ") in the expected bucket (" << sample << "). It has (" << actual_count
-      << ").";
-}
-
-void HistogramTester::CheckTotalCount(const std::string& name,
-                                      HistogramBase::Count expected_count,
-                                      const HistogramSamples& samples) const {
-  int actual_count = samples.TotalCount();
-  auto histogram_data = histograms_snapshot_.find(name);
-  if (histogram_data != histograms_snapshot_.end())
-    actual_count -= histogram_data->second->TotalCount();
-
-  EXPECT_EQ(expected_count, actual_count)
-      << "Histogram \"" << name
-      << "\" does not have the right total number of samples ("
-      << expected_count << "). It has (" << actual_count << ").";
-}
-
-bool Bucket::operator==(const Bucket& other) const {
-  return min == other.min && count == other.count;
-}
-
-void PrintTo(const Bucket& bucket, std::ostream* os) {
-  *os << "Bucket " << bucket.min << ": " << bucket.count;
-}
-
-}  // namespace base
diff --git a/base/test/histogram_tester.h b/base/test/histogram_tester.h
deleted file mode 100644
index 8019931..0000000
--- a/base/test/histogram_tester.h
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_TEST_HISTOGRAM_TESTER_H_
-#define BASE_TEST_HISTOGRAM_TESTER_H_
-
-#include <map>
-#include <memory>
-#include <ostream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_base.h"
-#include "base/time/time.h"
-
-namespace base {
-
-struct Bucket;
-class HistogramSamples;
-
-// HistogramTester provides a simple interface for examining histograms, UMA
-// or otherwise. Tests can use this interface to verify that histogram data is
-// getting logged as intended.
-//
-// Note: When using this class from a browser test, one might have to call
-// SubprocessMetricsProvider::MergeHistogramDeltasForTesting() to sync the
-// histogram data between the renderer and browser processes. If it is in a
-// content browser test, then content::FetchHistogramsFromChildProcesses()
-// should be used to achieve that.
-class HistogramTester {
- public:
-  using CountsMap = std::map<std::string, HistogramBase::Count>;
-
-  // Takes a snapshot of all current histograms counts.
-  HistogramTester();
-  ~HistogramTester();
-
-  // We know the exact number of samples in a bucket, and that no other bucket
-  // should have samples. Measures the diff from the snapshot taken when this
-  // object was constructed.
-  void ExpectUniqueSample(const std::string& name,
-                          HistogramBase::Sample sample,
-                          HistogramBase::Count expected_count) const;
-  template <typename T>
-  void ExpectUniqueSample(const std::string& name,
-                          T sample,
-                          HistogramBase::Count expected_count) const {
-    ExpectUniqueSample(name, static_cast<HistogramBase::Sample>(sample),
-                       expected_count);
-  }
-
-  // We know the exact number of samples in a bucket, but other buckets may
-  // have samples as well. Measures the diff from the snapshot taken when this
-  // object was constructed.
-  void ExpectBucketCount(const std::string& name,
-                         HistogramBase::Sample sample,
-                         HistogramBase::Count expected_count) const;
-  template <typename T>
-  void ExpectBucketCount(const std::string& name,
-                         T sample,
-                         HistogramBase::Count expected_count) const {
-    ExpectBucketCount(name, static_cast<HistogramBase::Sample>(sample),
-                      expected_count);
-  }
-
-  // We don't know the values of the samples, but we know how many there are.
-  // This measures the diff from the snapshot taken when this object was
-  // constructed.
-  void ExpectTotalCount(const std::string& name,
-                        HistogramBase::Count count) const;
-
-  // We know exact number of samples for buckets corresponding to a time
-  // interval. Other intervals may have samples too.
-  void ExpectTimeBucketCount(const std::string& name,
-                             TimeDelta sample,
-                             HistogramBase::Count count) const;
-
-  // Returns a list of all of the buckets recorded since creation of this
-  // object, as vector<Bucket>, where the Bucket represents the min boundary of
-  // the bucket and the count of samples recorded to that bucket since creation.
-  //
-  // Example usage, using gMock:
-  //   EXPECT_THAT(histogram_tester.GetAllSamples("HistogramName"),
-  //               ElementsAre(Bucket(1, 5), Bucket(2, 10), Bucket(3, 5)));
-  //
-  // If you build the expected list programmatically, you can use ContainerEq:
-  //   EXPECT_THAT(histogram_tester.GetAllSamples("HistogramName"),
-  //               ContainerEq(expected_buckets));
-  //
-  // or EXPECT_EQ if you prefer not to depend on gMock, at the expense of a
-  // slightly less helpful failure message:
-  //   EXPECT_EQ(expected_buckets,
-  //             histogram_tester.GetAllSamples("HistogramName"));
-  std::vector<Bucket> GetAllSamples(const std::string& name) const;
-
-  // Returns the value of the |sample| bucket for ths histogram |name|.
-  HistogramBase::Count GetBucketCount(const std::string& name,
-                                      HistogramBase::Sample sample) const;
-
-  // Finds histograms whose names start with |prefix|, and returns them along
-  // with the counts of any samples added since the creation of this object.
-  // Histograms that are unchanged are omitted from the result. The return value
-  // is a map whose keys are the histogram name, and whose values are the sample
-  // count.
-  //
-  // This is useful for cases where the code under test is choosing among a
-  // family of related histograms and incrementing one of them. Typically you
-  // should pass the result of this function directly to EXPECT_THAT.
-  //
-  // Example usage, using gmock (which produces better failure messages):
-  //   #include "testing/gmock/include/gmock/gmock.h"
-  // ...
-  //   base::HistogramTester::CountsMap expected_counts;
-  //   expected_counts["MyMetric.A"] = 1;
-  //   expected_counts["MyMetric.B"] = 1;
-  //   EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix("MyMetric."),
-  //               testing::ContainerEq(expected_counts));
-  CountsMap GetTotalCountsForPrefix(const std::string& prefix) const;
-
-  // Access a modified HistogramSamples containing only what has been logged
-  // to the histogram since the creation of this object.
-  std::unique_ptr<HistogramSamples> GetHistogramSamplesSinceCreation(
-      const std::string& histogram_name) const;
-
- private:
-  // Verifies and asserts that value in the |sample| bucket matches the
-  // |expected_count|. The bucket's current value is determined from |samples|
-  // and is modified based on the snapshot stored for histogram |name|.
-  void CheckBucketCount(const std::string& name,
-                        HistogramBase::Sample sample,
-                        Histogram::Count expected_count,
-                        const HistogramSamples& samples) const;
-
-  // Verifies that the total number of values recorded for the histogram |name|
-  // is |expected_count|. This is checked against |samples| minus the snapshot
-  // that was taken for |name|.
-  void CheckTotalCount(const std::string& name,
-                       Histogram::Count expected_count,
-                       const HistogramSamples& samples) const;
-
-  // Sets the value for |count| to be the value in the |sample| bucket. The
-  // bucket's current value is determined from |samples| and is modified based
-  // on the snapshot stored for histogram |name|.
-  void GetBucketCountForSamples(const std::string& name,
-                                HistogramBase::Sample sample,
-                                const HistogramSamples& samples,
-                                HistogramBase::Count* count) const;
-
-  // Used to determine the histogram changes made during this instance's
-  // lifecycle.
-  std::map<std::string, std::unique_ptr<HistogramSamples>> histograms_snapshot_;
-
-  DISALLOW_COPY_AND_ASSIGN(HistogramTester);
-};
-
-struct Bucket {
-  Bucket(HistogramBase::Sample min, HistogramBase::Count count)
-      : min(min), count(count) {}
-
-  bool operator==(const Bucket& other) const;
-
-  HistogramBase::Sample min;
-  HistogramBase::Count count;
-};
-
-void PrintTo(const Bucket& value, std::ostream* os);
-
-}  // namespace base
-
-#endif  // BASE_TEST_HISTOGRAM_TESTER_H_
diff --git a/base/threading/platform_thread_posix.cc b/base/threading/platform_thread_posix.cc
index a5ddb2e..c3a071b 100644
--- a/base/threading/platform_thread_posix.cc
+++ b/base/threading/platform_thread_posix.cc
@@ -15,7 +15,6 @@
 
 #include <memory>
 
-#include "base/debug/activity_tracker.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/threading/platform_thread_internal_posix.h"
@@ -220,9 +219,6 @@
 
 // static
 void PlatformThread::Join(PlatformThreadHandle thread_handle) {
-  // Record the event that this thread is blocking upon (for hang diagnosis).
-  base::debug::ScopedThreadJoinActivity thread_activity(&thread_handle);
-
   // Joining another thread may block the current thread for a long time, since
   // the thread referred to by |thread_handle| may still be running long-lived /
   // blocking tasks.
diff --git a/build/gen.py b/build/gen.py
index 988cc58..37592d4 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -237,7 +237,6 @@
         'base/callback_helpers.cc',
         'base/callback_internal.cc',
         'base/command_line.cc',
-        'base/debug/activity_tracker.cc',
         'base/debug/alias.cc',
         'base/debug/crash_logging.cc',
         'base/debug/dump_without_crashing.cc',
@@ -245,14 +244,12 @@
         'base/debug/task_annotator.cc',
         'base/debug/thread_heap_usage_tracker.cc',
         'base/environment.cc',
-        'base/feature_list.cc',
         'base/files/file.cc',
         'base/files/file_enumerator.cc',
         'base/files/file_path.cc',
         'base/files/file_path_constants.cc',
         'base/files/file_tracing.cc',
         'base/files/file_util.cc',
-        'base/files/important_file_writer.cc',
         'base/files/memory_mapped_file.cc',
         'base/files/scoped_file.cc',
         'base/files/scoped_temp_dir.cc',
@@ -281,24 +278,6 @@
         'base/message_loop/message_pump.cc',
         'base/message_loop/message_pump_default.cc',
         'base/message_loop/watchable_io_message_pump_posix.cc',
-        'base/metrics/bucket_ranges.cc',
-        'base/metrics/dummy_histogram.cc',
-        'base/metrics/field_trial.cc',
-        'base/metrics/field_trial_param_associator.cc',
-        'base/metrics/field_trial_params.cc',
-        'base/metrics/histogram.cc',
-        'base/metrics/histogram_base.cc',
-        'base/metrics/histogram_functions.cc',
-        'base/metrics/histogram_samples.cc',
-        'base/metrics/histogram_snapshot_manager.cc',
-        'base/metrics/metrics_hashes.cc',
-        'base/metrics/persistent_histogram_allocator.cc',
-        'base/metrics/persistent_memory_allocator.cc',
-        'base/metrics/persistent_sample_map.cc',
-        'base/metrics/sample_map.cc',
-        'base/metrics/sample_vector.cc',
-        'base/metrics/sparse_histogram.cc',
-        'base/metrics/statistics_recorder.cc',
         'base/observer_list_threadsafe.cc',
         'base/path_service.cc',
         'base/pending_task.cc',
